Association Mappings
Introduction
Association mappings are the often most difficult thing to get right. In
this section we'll go through the canonical cases one by one, starting
with unidirectional mappings, and then considering the bidirectional cases.
We'll use Person and Address in all
the examples.
We'll classify associations by whether or not they map to an intervening
join table, and by multiplicity.
Nullable foreign keys are not considered good practice in traditional data
modelling, so all our examples use not null foreign keys. This is not a
requirement of Hibernate, and the mappings will all work if you drop the
nullability constraints.
Unidirectional associations
many to one
A unidirectional many-to-one association is the most
common kind of unidirectional association.
]]>
one to one
A unidirectional one-to-one association on a foreign key
is almost identical. The only difference is the column unique constraint.
]]>
A unidirectional one-to-one association on a primary key
usually uses a special id generator. (Notice that we've reversed the direction
of the association in this example.)
person
]]>
one to many
A unidirectional one-to-many association on a foreign key
is a very unusual case, and is not really recommended.
]]>
We think it's better to use a join table for this kind of association.
Unidirectional associations with join tables
one to many
A unidirectional one-to-many association on a join table
is much preferred. Notice that by specifying unique="true",
we have changed the multiplicity from many-to-many to one-to-many.
]]>
many to one
A unidirectional many-to-one association on a join table
is quite common when the association is optional.
]]>
one to one
A unidirectional one-to-one association on a join table
is extremely unusual, but possible.
]]>
many to many
Finally, we have a unidirectional many-to-many association.
]]>
Bidirectional associations
one to many / many to one
A bidirectional many-to-one association is the
most common kind of association. (This is the standard parent/child
relationship.)
]]>
one to one
A bidirectional one-to-one association on a foreign key
is quite common.
]]>
A bidirectional one-to-one association on a primary key
uses the special id generator.
person
]]>
Bidirectional associations with join tables
one to many / many to one
A bidirectional one-to-many association on a join table.
Note that the inverse="true" can go on either end of the
association, on the collection, or on the join.
]]>
one to one
A bidirectional one-to-one association on a join table
is extremely unusual, but possible.
]]>
many to many
Finally, we have a bidirectional many-to-many association.
]]>
More complex association mappings
More complex association joins are extremely rare.
Hibernate makes it possible to handle more complex situations using
SQL fragments embedded in the mapping document. For example, if a table
with historical account information data defines
accountNumber, effectiveEndDate
and effectiveStartDatecolumns, mapped as follows:
case when effectiveEndDate is null then 1 else 0 end
]]>
Then we can map an association to the current instance
(the one with null effectiveEndDate) using:
'1'
]]>
In a more complex example, imagine that the association between
Employee and Organization is maintained
in an Employment table full of historical employment data.
Then an association to the employee's most recent employer
(the one with the most recent startDate) might be mapped this way:
select employeeId, orgId
from Employments
group by orgId
having startDate = max(startDate)
]]>
You can get quite creative with this functionality, but it is usually more practical
to handle these kinds of cases using HQL or a criteria query.