2010-07-15 7 views
0

Je suis confronté à un problème avec les relations de type parent enfant.
Les docs Hibernate disent d'ajouter une relation "many-to-one" dans la classe enfant pour obtenir la valeur de la clé étrangère du parent. Mais pour que cette relation fonctionne, je dois ajouter la propriété Invoice dans la classe enfant qui introduit une inclusion circulaire du parent dans l'enfant et casse mon sérialiseur. Quelqu'un pourrait-il indiquer où je me trompe?Problème avec la relation parent/enfant avec hibernate

Voici mon code:

Invoice.java

public class Invoice implements Serializable { 
    private Long id; 
    private Date invDate; 
    private String customer; 
    private Set<InvoiceItem> items; 
    ... getters/setters ... 
} 

InvoiceItem.java

public class InvoiceItem implements Serializable { 
    private Long itemId; 
    private long productId; 
    private int quantity; 
    private double price; 
    private Invoice invoice; //??????? 
    ... getters/setters ... 
} 

Invoice.hbm.xml

<class name="Invoice" table="Invoices"> 
    <id name="id" column="ID" type="long"> 
    <generator class="native" /> 
    </id> 
    <property name="invDate" type="timestamp" /> 
    <property name="customer" type="string" /> 

    <set name="items" inverse="true" cascade="all-delete-orphan"> 
    <key column="invoiceId" /> 
    <one-to-many class="InvoiceItem" /> 
    </set> 
</class> 

InvoiceItem.hbm.xml

<class name="InvoiceItem" table="InvoiceItems"> 
    <id name="itemId" type="long" column="id"> 
    <generator class="native" /> 
    </id> 

    <property name="productId" type="long" /> 
    <property name="quantity" type="int" /> 
    <property name="price" type="double" /> 

<many-to-one name="invoiceId" class="Invoice" not-null="true"/> <!--????????--> 
</class> 

Répondre

2

Vous n'avez pas besoin d'avoir une référence à Invoice in InvoiceItem si vous supprimez l'attribut inverse = "true". Hibernate crée alors une table de mappage distincte au lieu d'utiliser une clé étrangère dans la table InvoiceItem.

Supprimez l'attribut inverse sur l'ensemble InvoiceItem et supprimez également la propriété Invoice de InvoiceItem et le many-to-one correspondant dans le mappage et vous devriez obtenir ce que vous voulez. Vous pouvez également marquer la référence de facture dans InvoiceItem comme transitoire et manipuler la valeur lors de la désérialisation: parcourir l'ensemble d'éléments dans la facture et définir la propriété invoice de chaque élément sur la facture propriétaire.

+0

J'ai essayé la première option mais j'ai reçu une erreur: "Le champ 'invoiceId' n'a pas de valeur par défaut". (La clé étrangère BTW n'est pas notée dans DB et je ne veux pas la rendre nulle). Ici les documents hibernate suggèrent d'ajouter plusieurs-à-une relation dans la classe enfant que j'essaye d'éviter – WSK

+0

oublié de mentionner, ajouter not-null = "true" à l'élément sous dans la facture. – mdma

+0

génial. Les deux approches fonctionnent. L'un d'entre eux est-il préféré à l'autre? – WSK

Questions connexes