You may use a component as an identifier of an entity class. Your component class must satisfy certain requirements:
It must implement java.io.Serializable
.
It must re-implement equals()
and
hashCode()
, consistently with the database's
notion of composite key equality.
Note: in Hibernate3, the second requirement is not an absolutely hard requirement of Hibernate. But do it anyway.
You can't use an IdentifierGenerator
to generate composite keys.
Instead the application must assign its own identifiers.
Use the <composite-id>
tag (with nested
<key-property>
elements) in place of the usual
<id>
declaration. For example, the
OrderLine
class has a primary key that depends upon
the (composite) primary key of Order
.
<class name="OrderLine"> <composite-id name="id" class="OrderLineId"> <key-property name="lineId"/> <key-property name="orderId"/> <key-property name="customerId"/> </composite-id> <property name="name"/> <many-to-one name="order" class="Order" insert="false" update="false"> <column name="orderId"/> <column name="customerId"/> </many-to-one> .... </class>
Now, any foreign keys referencing the OrderLine
table are also
composite. You must declare this in your mappings for other classes. An association
to OrderLine
would be mapped like this:
<many-to-one name="orderLine" class="OrderLine"> <!-- the "class" attribute is optional, as usual --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </many-to-one>
(Note that the <column>
tag is an alternative to the
column
attribute everywhere.)
A many-to-many
association to OrderLine
also
uses the composite foreign key:
<set name="undeliveredOrderLines"> <key column name="warehouseId"/> <many-to-many class="OrderLine"> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </many-to-many> </set>
The collection of OrderLine
s in Order
would
use:
<set name="orderLines" inverse="true"> <key> <column name="orderId"/> <column name="customerId"/> </key> <one-to-many class="OrderLine"/> </set>
(The <one-to-many>
element, as usual, declares no columns.)
If OrderLine
itself owns a collection, it also has a composite
foreign key.
<class name="OrderLine"> .... .... <list name="deliveryAttempts"> <key> <!-- a collection inherits the composite key type --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </key> <list-index column="attemptId" base="1"/> <composite-element class="DeliveryAttempt"> ... </composite-element> </set> </class>