views:

262

answers:

3

I have a structure where the main table is USER, other tables include CATEGORY (contains user_id).

What I got after the standard reverse engineering procedure was:

  • the class User contained a collection of categories,
  • the class Category didn't contain the foreign key (user_id) but it did contain the User object.

Why did it not contain the foreign key as a class property?

And how do I join these two tables in HQL without that glue? HQL - please explain this part.

+3  A: 

Hibernate automatically handles the foreign key for you in this case. On the Java side, you don't need to think about foreign keys, but aggregation. That is why Category contains a (reference to a) User object, not an FK. The binding between the user property of class Category and the FK column in the USER table is specified in the Hibernate mapping.

If you then create a Criteria or a Query using these classes, Hibernate will automatically generate the SQL query using the proper FK. I don't have experience with HQL, but I am pretty sure Hibernate handles that one correctly as well.

Update: HQL example:

from Category as category inner join fetch category.user as user

Example adapted from here.

For more details on the mapping, see the Hibernate Reference, chapters 5 to 7.

Péter Török
I see. For me it would be natural to have both User object and the foreign key, both. Let's see what others will reply. Thank you.
EugeneP
@EugeneP see my updated explanation and the reference - hope it helps clarify the issue. Having _both_ the `User` object _and_ the FK in your Java class would be duplication, requiring more synchronization and opening up more possibilities for errors. Also, the PK and FK is (should be) often private to the DB (and this is the recommendation in Hibernate).
Péter Török
@EugeneP I added a HQL example and a reference.
Péter Török
@Péter Török Thank you for your full and helpful answer.
EugeneP
A: 

I agree with Péter Török : the current hibernate behaviour is the expected one.

For example, what should hibernate do when you update a Category where you modified the User but not the raw FK ?

Why would you need the raw FK ? you just have to do category.getUser().getId(); to have access to it, without risking inconsistent state in your Category object.

Thierry
+2  A: 

Why did it not contain the foreign key as a class property?

Because Hibernate is an Object-Relational Mapping tool, Hibernate allows to work with an object model (i.e. objects and relations between objects) and map them to the database representation (data rows of tables). The whole point of Hibernate is to bridge the gap between the object-oriented paradigm and the relational paradigm (the famous Object-Relational Impedance Mismatch). And in your case, this following object model is the expected (and right) object representation:

alt text

And how do I join these two tables in HQL without that glue?

The glue is there, but you have to think object (and association). For example (see 14.3. Associations and joins):

from Category as category join category.user as user

Note that HQL supports two forms of association joining: implicit and explicit (see 14.4. Forms of join syntax). The above example uses an explicit join. The implicit form doesn't use the join keyword but a dot-notation:

from Category category where category.user.id =: id
Pascal Thivent