7.1. Introduction

Association mappings are often the most difficult thing to implement correctly. In
this section we examine some canonical cases one by one, starting
with unidirectional mappings and then bidirectional cases.
We will use Person and Address in all
the examples.

Associations will be classified by multiplicity and whether or not they map to an intervening
join table.

Nullable foreign keys are not considered to be good practice in traditional data
modelling, so our examples do not use nullable foreign keys. This is not a
requirement of Hibernate, and the mappings will work if you drop the
nullability constraints.

7.2. Unidirectional associations

7.2.1. Many-to-one

A unidirectional many-to-one association is the most
common kind of unidirectional association.

If you use a List, or other indexed collection,
set the key column of the foreign key to not null.
Hibernate will manage the association from the collections side to maintain the index
of each element, making the other side virtually inverse by setting
update="false" and insert="false":

If the underlying foreign key column is NOT NULL, it
is important that you define not-null="true" on the
<key> element of the collection mapping.
Do not only
declare not-null="true" on a possible nested
<column> element, but on the <key>
element.

7.6. More complex association mappings

More complex association joins are extremely rare.
Hibernate handles more complex situations by using
SQL fragments embedded in the mapping document. For example, if a table
with historical account information data defines
accountNumber, effectiveEndDate
and effectiveStartDatecolumns, it would be mapped as follows:

<propertiesname="currentAccountKey"><propertyname="accountNumber"type="string"not-null="true"/><propertyname="currentAccount"type="boolean"><formula>case when effectiveEndDate is null then 1 else 0 end</formula></property></properties><propertyname="effectiveEndDate"type="date"/><propertyname="effectiveStateDate"type="date"not-null="true"/>

You can then map an association to the current instance,
the one with null effectiveEndDate, by using:

In a more complex example, imagine that the association between
Employee and Organization is maintained
in an Employment table full of historical employment data.
An association to the employee's most recent employer,
the one with the most recent startDate, could be mapped in the following way:

<join><keycolumn="employeeId"/><subselect> select employeeId, orgId from Employments group by orgId having startDate = max(startDate)</subselect><many-to-onename="mostRecentEmployer"class="Organization"column="orgId"/></join>

This functionality allows a degree of creativity and flexibility, but it is more practical
to handle these kinds of cases using HQL or a criteria query.