i am new to hibernate and want to know a few things. I want to implement the following query in hibernate,please guide me.
SELECT p.num_is_active
FROM ins.cnfgtr_user_log t, ins.service_user_auth p
WHERE t.source = 'GC'
and t.tokenid = p.txt_auth_token
and t.sessionid = 100000000195756
and t.userid = p.txt_user_id
and t.userid = 'MASTERADMIN'
I also want to know do i have to maintain two separate pojo's for these two tables? does this pojo's need to be complete? i mean do they need to contain all the columns of the tables or can they contain only the ones needed for this query?
Q: do i have to maintain two separate POJO's for these two tables?
Answer: Yes you suppose to. Here in ORM each table will be represented by separate POJOs for modularity reasons.
Q: does this POJO's need to be complete?
Answer: Need not be. Except the columns marked as “not null”. You can use JPA/Hibernate Joins for querying purpose.
Hope this is helpful!
Related
I'm creating a very simple application in Java that will be storing questions in an embedded Derby database. I've decided to use the DAO pattern for accessing the data in the database. I cannot make use of an ORM for this project.
A question will have data that I would normally model using a many to one relationship in a relational database. An example of this data would be:
A question will have one category. One category will have multiple questions.
A question will have a score of 1000, 2000 or 3000. A score will have many questions.
With the above in mind, I would create three tables (brackets indicate columns):
Question (id, question, scoreId, categoryId)
Score (id, score)
Category (id, category)
My first question is:
Would modelling my data across three tables like I suggest above be bad practice/the wrong way to go about this? Is there any benefit in storing score and category in separate tables? Or would it be better to combine them into the Question table? A many to one relationship that links to a table with a single column (with the exception of id) seems redundant to me, as instead of storing an id referencing the Score/Category table, we can simply store the value of the category/score (since the category/score table does not store any additional information).
My second question is:
If modelling my data across separate tables is the correct approach, then how would I access the data using the DAO pattern? My confusion comes from the following:
I would create a DAO to populate a Question model object that would look a little something like this:
public class Question {
String question;
String category;
Integer score;
}
I would create a concrete implementation of the DAO interface like this:
public class QuestionAccessObject implements QuestionDao {
private static final String TABLE_1 = "QUESTION";
private static final String TABLE_2 = "SCORE";
private static final String TABLE_3 = "CATEGORY";
#Override
public List<Question> getAllQuestions() {
List<Question> questions = new ArrayList<>();
//Run a query with joins across the three tables and iterate over the result to populate the list
return questions;
}
}
Shouldn't each DAO object only be concerned with a single table in the database? My approach listed above doesn't seem like the most correct way to go about this. Seperate tables would also make inserting data into the database very messy (I don't understand how I could take clean approach using the DAO pattern and multiple tables). Creating a DAO for the Score and Category tables just wouldn't really make sense.. (and if I did this, how would I populate my model?)
Would modelling my data across three tables like I suggest above be bad practice/the wrong way to go about this? Is there any benefit in storing score and category in separate tables....?
It's a matter of discussion. In case of score I rather stick this information with the question. On the other hand, the category would be in the separated table since more of the question would share the same category, so it makes a perfect sense.
Shouldn't each DAO object only be concerned with a single table in the database?
Yes, DAO, an object should be concerned with a single source of data - as you say. I would certainly try to avoid any ComplexDao since those classes tend to get more complex and the number of methods increases over the time.
There exist a service layer to combine those results together and provide an output to the controller using the very same service.
Modeling the data across separate tables is A correct approach (not necessarily the best).
Separating tables helps database normalization: https://en.wikipedia.org/wiki/Database_normalization.
One could argue that the DAO pattern implies that each DAO object is concerned with a single entity . Similar to how ORMs work, an entity could easily reference other entities.
When you query for a question you could also just return the category and score ids inside the question object and force the library user to fetch the score value and category value (lazy fetch) using those id values with their respective DAOs (score and category).
So I believe that what you're doing seems fine
Hope this helps
I have two tables - Table1 and Table2. Data structure of both the tables is same.
I have single VO for both Table1 and Table2. I have two .hbm.xml file for two tables separately -
Table1.hbm.xml and Table2.hbm.xml
In my java code, based on a condition I either need to save to Table1 or Table2
if(someCondition)
{
session.saveOrUpdate(VO); //This should be for Table1
}
else
{
session.saveOrUpdate(VO); //This should be for Table2
}
My problem is since that VO is same, there will be conflict in deciding which table to save.
Is it possible to have same VO mapped to two tables?
Note: The reason why I have such a requirement is Table1 and Table2 are in separate tablespace. One is partitioned and the other is not.
There are couple of other reasons for such a weird requirement which is beyond my control to change the architecture now.
In my opinion using two entity managers is a bit too much. What you need is to have a good abstraction around the table.
You can map the same class as many times you want you just have to map it under different name.
Than one good Repository pattern working with the abstract entity (instead of the concrete one) combined with a Factory or Builder to generate the two objects will get the job done. If you follow this approach you will not need to have this IF-ELSE flow.
#MappedSuperClass
class AbstractMappedSomeTimes {
private mappedAttribute;
}
#Table("yourtablename")
public class MappedOnce extends AbstractEntity{
}
#Table("yourtablename")
public class MappedTwise extends AbstractEntity{
}
Than you can have Repository working with AbstractMappedSomeTimes types of objects. You can also create a Factory that will generate either MappedOnce objects or MappedTwise objects.
Hi i am trying to implement a simple join algorithim in Java...
I have three relations i.e M(ABX) N(ACY) and O(BCZ). These relations are currently in a comma separated file and all integers(example file M will have values like 1,5,6; 2,7.9;..) was wondering what was the best data structure to use in Java to implement the join MxNxO i.e M and N will join on attribute A producing a schema(ABCXY) which will then join with O on attributes B and C producing a final result of ABXCYZ which will have all join results..
Perhaps an embedded database like hsqldb would be the right choice. It's flexible, performant, and easy to use.
There is no specialized data structures that you can readily use for this.
You would have to represent the tables extracted from your CSV files via List<List>> and then you would have to iterate over the lists and compare the proper attribute representing the column name to create intermediate lists and so on until you have joined all the relations.
I.e. you would need to implement this logic yourself.
The best way for this IMHO is to follow the answer of #Ernest Friedman-Hill.
Not only will you get this functionality faster you will get it error free as you would not need to test that the join algorithm works correctly over any dataset. The embedded database will do this for you.
I'd like to explore Hibernate and used it in my project instead of JDBC.
My table design is highly normalized.
Suppose, I have this use case: Each insurance applied by a customer has one associated rateplan. Usually, in RDBMS this is implemented using two tables like below.
Table Insurance:
id long;
accountHolder varchar;
ratePlanId int; -->Rate Plan Id is Foreign Key to the RatePlanTable
Table RatePlan:
ratePlanId int;
ratePlanDesc varchar;
discountRate double;
Now, my question is..does this qualify as a onetomany relationship?
Most of the examples that I am seeing on the net regarding onetomany, involves some sort of collections (e.g An Order has a list of products). And when represented in class is translated below, which I think is really a one to many case?
public class Order{
private List products;
}
But how about my case? I don't think that it is a onetomany or I am just mislead by the examples?
How can I do a hbm mapping for my two classes? In my case, I would create two class to represent the two tables, but I am not sure how the hbm.xml would look like for the two class.
Yes, it is a one to many relationship, in that one rate plan is associated with many insurance policies. In entity traversal, when you would go from the Policy, you would get one Plan object, and conversely, from a Plan object, you would get a list of Policy objects.
I'm mapping a proprietary database to Hibernate for use with Spring. In it, there are a couple of jointables that, for entity A and entity B have the following schema:
CREATE TABLE AjoinB (
idA int not null,
idB int not null,
groupEnum enum ('groupC', 'groupD', 'groupE'),
primary key(idA, idB, groupEnum)
);
As you can see, this indicates that there can be multiple A-B relationships that put them in different groups. I'd like to end up with, first line for entity A and second for entity B, the following sets
Set<B> BforGroupC, BforGroupD, BforGroupE;
Set<A> AforGroupC, AforGroupD, AforGroupE;
So far, I've only managed to put them in one set and disregard the groupEnum relationship attribute:
#ManyToMany(targetEntity=B.class, cascade={ CascadeType.PERSIST, CascadeType.MERGE } )
#JoinTable(name="AjoinB", joinColumns=#JoinColumn(name="idA"), inverseJoinColumns=#JoinColumn(name="idB") )
private Set<B> BforAllGroups;
and
#ManyToMany( mappedBy = "BforAllGroups", targetEntity = A.class )
private Set<A> AforAllGroups;
How can I make multiple sets where they belong either in groupC, groupD or groupE?
Cheers
Nik
If you're considering doing this, don't. Tables are cheap nowadays what's with the economy and all, so just create one per association; it'll be so much easier.
If you're bound by a legacy database and you can't change the structure of that table I would
Consider skaffman's solution first (+1, btw). Depending on your target database you may be able to write a trigger for your views that would insert adequate "discriminator" value.
If the above isn't possible in your DB, another solution is to use custom SQL for CRUD operations for your collections. Keep in mind that this will NOT work (e.g. your "discriminator value" won't get applied) for complex HQL queries involving your association as part of condition. You can also mix / match this with above - e.g. use views and use custom SQL for insert / delete.
If both of the above fail, go with "association as a separate entity" as suggested by framer8. That's going to be rather ugly (since we're assuming here you can't change your tables) due to composite keys and all extraneous code. It may, in fact, be impossible if any of your associations allows duplicates.
To my knowledge, Hibernate cannot use such a "discriminator" column in the way that you want. Hibernate requires a join table for each of them.
Perhaps you might be able to define additional views on the table, showing each of the groupings?
I think the advise anytime you need to access a field in a link table is to make the link table an object and a hibernate entity in its own right. A would have a set of AtoB objects and AtoB would have a set of B objects. I have a simmilar situation where the link table has a user associated with the link.
select joinTable.b from A a
left join a.AtoB joinTable
where joinTable.group = 'C'
It's not as elegant as having an implicit join done by hibernate, but it does give you the control you need.