8.4. Utiliser un composant comme identifiant

Vous pouvez utiliser un composant comme identifiant d'une entité. Mais pour cela la classe du composant doit respecter certaines règles.

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 OrderLines 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>