Vous pouvez utiliser un composant comme identifiant d'une entité. Mais pour cela la classe du composant doit respecter certaines règles.
Elle doit implémenter java.io.Serializable
.
Elle doit redéfinir equals()
et hashCode()
, de façon cohérente avec le fait qu'elle définit une clé composite dans la base de données.
Remarque: avec hibernate3, la seconde règle n'est plus absolument necessaire mais faîtes le quand même.
Vous ne pouvez pas utiliser de IdentifierGenerator
pour générer une clé composite, l'application devra définir elle même ses propres identifiants.
Utiliser l'élément <composite-id>
(en incluant l'élément <key-property>
) à la place de l'habituel déclaration <id>
. Par exemple la classe OrderLine
qui dépend de la clé primaire (composite) de 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>
Maintenant toutes clés étrangères référençant la table OrderLine
devra aussi être composite. Vous devez en tenir compte lorsque vous écrivez vos mapping d'association pour les autres classes.
Une association à OrderLine
devrait être mappé de la façon suivante :
<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>
(Remarque: l'élément <column>
est une alternative à l'attribut column
que l'on utilise partout.)
Une association plusieurs-à-plusieurs
(many-to-many) à OrderLine
utilisera aussi une clé étrangère composite:
<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>
La collection des OrderLine
s dans Order
utilisera:
<set name="orderLines" inverse="true"> <key> <column name="orderId"/> <column name="customerId"/> </key> <one-to-many class="OrderLine"/> </set>
(L'élément <one-to-many>
, comme d'habitude, ne déclare pas de colonne.)
Si OrderLine
lui-même possède une collection, celle-ci aura aussi une clé composite étrangère.
<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>