484 lines
20 KiB
XML
484 lines
20 KiB
XML
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
|||
|
<chapter id="inheritance">
|
|||
|
<title>Mapping d'h<>ritage de classe</title>
|
|||
|
|
|||
|
<sect1 id="inheritance-strategies" revision="3">
|
|||
|
<title>Les trois strat<61>gies</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Hibernate supporte les trois strat<61>gies d'h<>ritage de base :
|
|||
|
</para>
|
|||
|
|
|||
|
<itemizedlist>
|
|||
|
<listitem>
|
|||
|
<para>
|
|||
|
une table par hi<68>rarchie de classe (table per class hierarchy)
|
|||
|
</para>
|
|||
|
</listitem>
|
|||
|
<listitem>
|
|||
|
<para>
|
|||
|
une table par classe fille (table per subclass)
|
|||
|
</para>
|
|||
|
</listitem>
|
|||
|
<listitem>
|
|||
|
<para>
|
|||
|
une table par classe concr<63>te (table per concrete class)
|
|||
|
</para>
|
|||
|
</listitem>
|
|||
|
</itemizedlist>
|
|||
|
|
|||
|
<para>
|
|||
|
Hibernate supporte en plus une quatri<72>mestrat<61>gie, l<>g<EFBFBD>rement diff<66>rente, qui supporte le polymorphisme :
|
|||
|
</para>
|
|||
|
|
|||
|
<itemizedlist>
|
|||
|
<listitem>
|
|||
|
<para>
|
|||
|
le polymorphisme implicite
|
|||
|
</para>
|
|||
|
</listitem>
|
|||
|
</itemizedlist>
|
|||
|
|
|||
|
<para>
|
|||
|
Il est possible d'utiliser diff<66>rentes strat<61>gies de mapping pour diff<66>rentes branches d'une m<>me
|
|||
|
hi<68>rarchie d'h<>ritage, et alors d'employer le polymorphisme implicite pour r<>aliser le
|
|||
|
polymorphisme <20> travers toute la hi<68>rarchie. Pourtant, Hibernate ne supporte pas de m<>langer
|
|||
|
des mappings <literal><subclass></literal> et
|
|||
|
<literal><joined-subclass></literal> et <literal><union-subclass></literal>
|
|||
|
pour le m<>me <20>l<EFBFBD>ment <literal><class></literal> racine.
|
|||
|
Il est possible de m<>langer ensemble les strat<61>gies d'une table par hi<68>rarchie et d'une
|
|||
|
table par sous-classe, pour le m<>me <20>l<EFBFBD>ment <literal><class></literal>, en combinant
|
|||
|
les <20>l<EFBFBD>ments <literal><subclass></literal> et <literal><join></literal> (voir dessous).
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
Il est possible de d<>finir des mappings de <literal>subclass</literal>, <literal>union-subclass</literal>,
|
|||
|
et <literal>joined-subclass</literal> dans des documents de mapping s<>par<61>s, directement sous
|
|||
|
<literal>hibernate-mapping</literal>. Ceci vous permet d'<27>tendre une hi<68>rarchie de classe juste en
|
|||
|
ajoutant un nouveau fichier de mapping. Vous devez sp<73>cifier un attribut <literal>extends</literal>
|
|||
|
dans le mapping de la sous-classe, en nommant une super-classe pr<70>c<EFBFBD>demment mapp<70>e. Note :
|
|||
|
pr<70>c<EFBFBD>demment cette foncionnalit<69> rendait l'ordre des documents de mapping important. Depuis
|
|||
|
Hibernate3, l'ordre des fichier de mapping n'importe plus lors de l'utilisation du mot-clef "extends".
|
|||
|
L'ordre <20> l'int<6E>rieur d'un simple fichier de mapping impose encore de d<>finir les classes m<>res
|
|||
|
avant les classes filles.
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[
|
|||
|
<hibernate-mapping>
|
|||
|
<subclass name="DomesticCat" extends="Cat" discriminator-value="D">
|
|||
|
<property name="name" type="string"/>
|
|||
|
</subclass>
|
|||
|
</hibernate-mapping>]]></programlisting>
|
|||
|
|
|||
|
|
|||
|
<sect2 id="inheritance-tableperclass" >
|
|||
|
<title>Une table par hi<68>rarchie de classe</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Supposons que nous ayons une interface <literal>Payment</literal>, impl<70>ment<6E>e
|
|||
|
par <literal>CreditCardPayment</literal>, <literal>CashPayment</literal>,
|
|||
|
<literal>ChequePayment</literal>. La strat<61>gie une table par hi<68>rarchie serait :
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="Payment" table="PAYMENT">
|
|||
|
<id name="id" type="long" column="PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<discriminator column="PAYMENT_TYPE" type="string"/>
|
|||
|
<property name="amount" column="AMOUNT"/>
|
|||
|
...
|
|||
|
<subclass name="CreditCardPayment" discriminator-value="CREDIT">
|
|||
|
<property name="creditCardType" column="CCTYPE"/>
|
|||
|
...
|
|||
|
</subclass>
|
|||
|
<subclass name="CashPayment" discriminator-value="CASH">
|
|||
|
...
|
|||
|
</subclass>
|
|||
|
<subclass name="ChequePayment" discriminator-value="CHEQUE">
|
|||
|
...
|
|||
|
</subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Une seule table est requise. Une grande limitation de cette
|
|||
|
strat<61>gie est que les colonnes d<>clar<61>es par les classes filles, telles que <literal>CCTYPE</literal>,
|
|||
|
ne peuvent avoir de contrainte <literal>NOT NULL</literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritance-tablepersubclass">
|
|||
|
<title>Une table par classe fille</title>
|
|||
|
|
|||
|
<para>
|
|||
|
La strat<61>gie une table par classe fille serait :
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="Payment" table="PAYMENT">
|
|||
|
<id name="id" type="long" column="PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<property name="amount" column="AMOUNT"/>
|
|||
|
...
|
|||
|
<joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
<property name="creditCardType" column="CCTYPE"/>
|
|||
|
...
|
|||
|
</joined-subclass>
|
|||
|
<joined-subclass name="CashPayment" table="CASH_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
...
|
|||
|
</joined-subclass>
|
|||
|
<joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
...
|
|||
|
</joined-subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Quatre tables sont requises. Les trois tables des classes filles ont
|
|||
|
une cl<63> primaire associ<63>e <20> la table classe m<>re (le mod<6F>le relationnel
|
|||
|
est une association un-vers-un).
|
|||
|
</para>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
|
|||
|
<title>Une table par classe fille, en utilisant un discriminant</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Notez que l'impl<70>mentation Hibernate de la strat<61>gie un table par
|
|||
|
classe fille ne n<>cessite pas de colonne discriminante dans la table
|
|||
|
classe m<>re. D'autres impl<70>mentations de mappers Objet/Relationnel utilisent
|
|||
|
une autre impl<70>mentation de la strat<61>gie une table par classe fille qui n<>cessite
|
|||
|
une colonne de type discriminant dans la table de la classe m<>re. L'approche
|
|||
|
prise par Hibernate est plus difficile <20> impl<70>menter mais plus correcte
|
|||
|
d'une point de vue relationnel. Si vous aimeriez utiliser
|
|||
|
une colonne discriminante avec la strat<61>gie d'une table par classe fille, vous pourriez combiner
|
|||
|
l'utilisation de <literal><subclass></literal> et
|
|||
|
<literal><join></literal>, comme suit :
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="Payment" table="PAYMENT">
|
|||
|
<id name="id" type="long" column="PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<discriminator column="PAYMENT_TYPE" type="string"/>
|
|||
|
<property name="amount" column="AMOUNT"/>
|
|||
|
...
|
|||
|
<subclass name="CreditCardPayment" discriminator-value="CREDIT">
|
|||
|
<join table="CREDIT_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
<property name="creditCardType" column="CCTYPE"/>
|
|||
|
...
|
|||
|
</join>
|
|||
|
</subclass>
|
|||
|
<subclass name="CashPayment" discriminator-value="CASH">
|
|||
|
<join table="CASH_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
...
|
|||
|
</join>
|
|||
|
</subclass>
|
|||
|
<subclass name="ChequePayment" discriminator-value="CHEQUE">
|
|||
|
<join table="CHEQUE_PAYMENT" fetch="select">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
...
|
|||
|
</join>
|
|||
|
</subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
La d<>claration optionnelle <literal>fetch="select"</literal> indique <20> Hibernate
|
|||
|
de ne pas r<>cup<75>rer les donn<6E>es de la classe fille <literal>ChequePayment</literal> par une jointure externe lors des requ<71>tes sur la classe m<>re.
|
|||
|
</para>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
|
|||
|
<title>M<EFBFBD>lange d'une table par hi<68>rarchie de classe avec une table par classe fille</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Vous pouvez m<>me m<>langer les strat<61>gies d'une table par hi<68>rarchie de classe et d'une table par classe fille en utilisant cette approche :
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="Payment" table="PAYMENT">
|
|||
|
<id name="id" type="long" column="PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<discriminator column="PAYMENT_TYPE" type="string"/>
|
|||
|
<property name="amount" column="AMOUNT"/>
|
|||
|
...
|
|||
|
<subclass name="CreditCardPayment" discriminator-value="CREDIT">
|
|||
|
<join table="CREDIT_PAYMENT">
|
|||
|
<property name="creditCardType" column="CCTYPE"/>
|
|||
|
...
|
|||
|
</join>
|
|||
|
</subclass>
|
|||
|
<subclass name="CashPayment" discriminator-value="CASH">
|
|||
|
...
|
|||
|
</subclass>
|
|||
|
<subclass name="ChequePayment" discriminator-value="CHEQUE">
|
|||
|
...
|
|||
|
</subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Pour importe laquelle de ces strat<61>gies, une association polymorphique vers la classe racine
|
|||
|
<literal>Payment</literal> est mapp<70>e en utilisant <literal><many-to-one></literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritance-tableperconcrete" revision="2">
|
|||
|
<title>Une table par classe concr<63>te</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Il y a deux mani<6E>res d'utiliser la strat<61>gie d'une table par classe concr<63>te. La premi<6D>re
|
|||
|
est d'employer <literal><union-subclass></literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="Payment">
|
|||
|
<id name="id" type="long" column="PAYMENT_ID">
|
|||
|
<generator class="sequence"/>
|
|||
|
</id>
|
|||
|
<property name="amount" column="AMOUNT"/>
|
|||
|
...
|
|||
|
<union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
|
|||
|
<property name="creditCardType" column="CCTYPE"/>
|
|||
|
...
|
|||
|
</union-subclass>
|
|||
|
<union-subclass name="CashPayment" table="CASH_PAYMENT">
|
|||
|
...
|
|||
|
</union-subclass>
|
|||
|
<union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
|
|||
|
...
|
|||
|
</union-subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Trois tables sont n<>cessaires pour les classes filles. Chaque table d<>finit des colonnes
|
|||
|
pour toutes les propri<72>t<EFBFBD>s de la classe, incluant les propri<72>t<EFBFBD>s h<>rit<69><74>s.
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
La limitation de cette approche est que si une propri<72>t<EFBFBD> est mapp<70>e sur la classe m<>re, le nom
|
|||
|
de la colonne doit <20>tre le m<>me pour toutes les classes filles. (Nous pourrions <20>tre plus souple
|
|||
|
dans une future version d'Hibernate).
|
|||
|
La strat<61>gie du g<>n<EFBFBD>rateur d'identifiant n'est pas permise dans l'h<>ritage de classes filles par
|
|||
|
union, en effet la valeur (NdT : seed) de la clef primaire
|
|||
|
doit <20>tre partag<61>e par toutes les classes filles "union" d'une hi<68>rarchie.
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
Si votre classe m<>re est abstraite, mappez la avec <literal>abstract="true"</literal>.
|
|||
|
Bien s<>r, si elle n'est pas abstraite, une table suppl<70>mentaire (par d<>faut,
|
|||
|
<literal>PAYMENT</literal> dans l'exemple ci-dessus) est requise pour contenir des instances
|
|||
|
de la classe m<>re.
|
|||
|
</para>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritance-tableperconcreate-polymorphism">
|
|||
|
<title>Une table par classe concr<63>te, en utilisant le polymorphisme implicite</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Une approche alternative est l'emploi du polymorphisme implicite :
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
|
|||
|
<id name="id" type="long" column="CREDIT_PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<property name="amount" column="CREDIT_AMOUNT"/>
|
|||
|
...
|
|||
|
</class>
|
|||
|
|
|||
|
<class name="CashPayment" table="CASH_PAYMENT">
|
|||
|
<id name="id" type="long" column="CASH_PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<property name="amount" column="CASH_AMOUNT"/>
|
|||
|
...
|
|||
|
</class>
|
|||
|
|
|||
|
<class name="ChequePayment" table="CHEQUE_PAYMENT">
|
|||
|
<id name="id" type="long" column="CHEQUE_PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<property name="amount" column="CHEQUE_AMOUNT"/>
|
|||
|
...
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Notez que nulle part nous ne mentionnons l'interface <literal>Payment</literal> explicitement.
|
|||
|
Notez aussi que des propri<72>t<EFBFBD>s de <literal>Payment</literal> sont mapp<70>es dans
|
|||
|
chaque classe fille. Si vous voulez <20>viter des duplications, consid<69>rez l'utilisation des
|
|||
|
entit<69>s XML (cf. <literal>[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]</literal>
|
|||
|
dans la d<>claration du <literal>DOCTYPE</literal> et <literal>&allproperties;</literal> dans le mapping).
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
L'inconv<6E>nient de cette approche est qu'Hibernate ne g<>n<EFBFBD>re pas d'<literal>UNION</literal>s SQL
|
|||
|
lors de l'ex<65>cution des requ<71>tes polymorphiques.
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
Pour cette strat<61>gie de mapping, une association polymorphique pour <literal>Payment</literal>
|
|||
|
est habituellement mapp<70>e en utilisant <literal><any></literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
|
|||
|
<meta-value value="CREDIT" class="CreditCardPayment"/>
|
|||
|
<meta-value value="CASH" class="CashPayment"/>
|
|||
|
<meta-value value="CHEQUE" class="ChequePayment"/>
|
|||
|
<column name="PAYMENT_CLASS"/>
|
|||
|
<column name="PAYMENT_ID"/>
|
|||
|
</any>]]></programlisting>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
<sect2 id="inheritace-mixingpolymorphism">
|
|||
|
<title>M<EFBFBD>lange du polymorphisme implicite avec d'autres mappings d'h<>ritage</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Il y a une chose suppl<70>mentaire <20> noter <20> propos de ce mapping. Puisque les classes filles sont
|
|||
|
chacune mapp<70>es avec leur propre <20>l<EFBFBD>ment <literal><class></literal> (et puisque
|
|||
|
<literal>Payment</literal> est juste une interface), chaque classe fille pourrait
|
|||
|
facilement faire partie d'une autre hi<68>rarchie
|
|||
|
d'h<>ritage ! (Et vous pouvez encore faire des requ<71>tes polymorphiques pour l'interface <literal>Payment</literal>).
|
|||
|
</para>
|
|||
|
|
|||
|
<programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
|
|||
|
<id name="id" type="long" column="CREDIT_PAYMENT_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
<discriminator column="CREDIT_CARD" type="string"/>
|
|||
|
<property name="amount" column="CREDIT_AMOUNT"/>
|
|||
|
...
|
|||
|
<subclass name="MasterCardPayment" discriminator-value="MDC"/>
|
|||
|
<subclass name="VisaPayment" discriminator-value="VISA"/>
|
|||
|
</class>
|
|||
|
|
|||
|
<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
|
|||
|
<id name="id" type="long" column="TXN_ID">
|
|||
|
<generator class="native"/>
|
|||
|
</id>
|
|||
|
...
|
|||
|
<joined-subclass name="CashPayment" table="CASH_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
<property name="amount" column="CASH_AMOUNT"/>
|
|||
|
...
|
|||
|
</joined-subclass>
|
|||
|
<joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
|
|||
|
<key column="PAYMENT_ID"/>
|
|||
|
<property name="amount" column="CHEQUE_AMOUNT"/>
|
|||
|
...
|
|||
|
</joined-subclass>
|
|||
|
</class>]]></programlisting>
|
|||
|
|
|||
|
<para>
|
|||
|
Encore une fois, nous ne mentionnons pas explicitement <literal>Payment</literal>.
|
|||
|
Si nous ex<65>cutons une requ<71>te sur l'interface <literal>Payment</literal> - par
|
|||
|
exemple, <literal>from Payment</literal> - Hibernate retournera
|
|||
|
automatiquement les instances de <literal>CreditCardPayment</literal>
|
|||
|
(et ses classes filles puisqu'elles impl<70>mentent aussi <literal>Payment</literal>),
|
|||
|
<literal>CashPayment</literal> et <literal>ChequePayment</literal> mais pas
|
|||
|
les instances de <literal>NonelectronicTransaction</literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
</sect2>
|
|||
|
|
|||
|
</sect1>
|
|||
|
|
|||
|
<sect1 id="inheritance-limitations">
|
|||
|
<title>Limitations</title>
|
|||
|
|
|||
|
<para>
|
|||
|
Il y a certaines limitations <20> l'approche du "polymorphisme implicite"
|
|||
|
pour la strat<61>gie de mapping d'une table par classe concr<63>te.
|
|||
|
Il y a plut<75>t moins de limitations restrictives aux mappings <literal><union-subclass></literal>.
|
|||
|
</para>
|
|||
|
|
|||
|
<para>
|
|||
|
La table suivante montre les limitations des mappings d'une table par classe concr<63>te, et du polymorphisme implicite, dans Hibernate.
|
|||
|
</para>
|
|||
|
|
|||
|
<table frame="topbot">
|
|||
|
<title>Caract<EFBFBD>ristiques du mapping d'h<>ritage</title>
|
|||
|
<tgroup cols='8' align='left' colsep='1' rowsep='1'>
|
|||
|
<colspec colname='c1' colwidth="1*"/>
|
|||
|
<colspec colname='c2' colwidth="1*"/>
|
|||
|
<colspec colname='c3' colwidth="1*"/>
|
|||
|
<colspec colname='c4' colwidth="1*"/>
|
|||
|
<colspec colname='c5' colwidth="1*"/>
|
|||
|
<colspec colname='c6' colwidth="1*"/>
|
|||
|
<colspec colname='c7' colwidth="1*"/>
|
|||
|
<colspec colname='c8' colwidth="1*"/>
|
|||
|
<thead>
|
|||
|
<row>
|
|||
|
<entry>Strat<EFBFBD>gie d'h<>ritage</entry>
|
|||
|
<entry>many-to-one polymorphique</entry>
|
|||
|
<entry>one-to-one polymorphique</entry>
|
|||
|
<entry>one-to-many polymorphique</entry>
|
|||
|
<entry>many-to-many polymorphique</entry>
|
|||
|
<entry><literal>load()/get()</literal> polymorphique</entry>
|
|||
|
<entry>Requ<EFBFBD>tes polymorphiques</entry>
|
|||
|
<entry>Jointures polymorphiques</entry>
|
|||
|
<entry>R<EFBFBD>cup<EFBFBD>ration par jointure externe</entry>
|
|||
|
</row>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<row>
|
|||
|
<entry>une table par hi<68>rarchie de classe</entry>
|
|||
|
<entry><literal><many-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-many></literal></entry>
|
|||
|
<entry><literal><many-to-many></literal></entry>
|
|||
|
<entry><literal>s.get(Payment.class, id)</literal></entry>
|
|||
|
<entry><literal>from Payment p</literal></entry>
|
|||
|
<entry><literal>from Order o join o.payment p</literal></entry>
|
|||
|
<entry><emphasis>support<EFBFBD>e</emphasis></entry>
|
|||
|
</row>
|
|||
|
<row>
|
|||
|
<entry>une table par classe fille</entry>
|
|||
|
<entry><literal><many-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-many></literal></entry>
|
|||
|
<entry><literal><many-to-many></literal></entry>
|
|||
|
<entry><literal>s.get(Payment.class, id)</literal></entry>
|
|||
|
<entry><literal>from Payment p</literal></entry>
|
|||
|
<entry><literal>from Order o join o.payment p</literal></entry>
|
|||
|
<entry><emphasis>support<EFBFBD>e</emphasis></entry>
|
|||
|
</row>
|
|||
|
<row>
|
|||
|
<entry>une table par classe concr<63>te (union-subclass)</entry>
|
|||
|
<entry><literal><many-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-one></literal></entry>
|
|||
|
<entry><literal><one-to-many></literal> (pour <literal>inverse="true"</literal> seulement)</entry>
|
|||
|
<entry><literal><many-to-many></literal></entry>
|
|||
|
<entry><literal>s.get(Payment.class, id)</literal></entry>
|
|||
|
<entry><literal>from Payment p</literal></entry>
|
|||
|
<entry><literal>from Order o join o.payment p</literal></entry>
|
|||
|
<entry><emphasis>support<EFBFBD>e</emphasis></entry>
|
|||
|
</row>
|
|||
|
<row>
|
|||
|
<entry>une table par classe concr<63>te (polymorphisme implicite)</entry>
|
|||
|
<entry><literal><any></literal></entry>
|
|||
|
<entry><emphasis>non support<72></emphasis></entry>
|
|||
|
<entry><emphasis>non support<72></emphasis></entry>
|
|||
|
<entry><literal><many-to-any></literal></entry>
|
|||
|
<entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
|
|||
|
<entry><literal>from Payment p</literal></entry>
|
|||
|
<entry><emphasis>non support<72>es</emphasis></entry>
|
|||
|
<entry><emphasis>non support<72>e</emphasis></entry>
|
|||
|
</row>
|
|||
|
</tbody>
|
|||
|
</tgroup>
|
|||
|
</table>
|
|||
|
|
|||
|
</sect1>
|
|||
|
|
|||
|
</chapter>
|