2009-12-16 4 views
0

Je suis en train d'apprendre NHibernate. J'ai utilisé des exemples de la documentation et ici à stackoverflow, mais il me manque quelque chose. J'ai un objet PARENT qui a une collection de CHILD. Un enfant n'a pas de signification sans un parent, donc la base de données a FK défini sur NOT NULL. La mise en œuvre de NHibernate de CHILD à PARENT fonctionne bien, même si je n'ai pas besoin de cette direction de relation. Au lieu de cela, j'ai essayé d'implémenter le parent possédant la relation, mais je reçois constamment une erreur de base de données bouillonnant "Impossible d'insérer la valeur NULL dans PARENT_ID". Ni l'ID ni l'entité du PARENT ne sont stockés dans l'ENFANT lors de l'enregistrement.Le mappage parent NHibernate ne crée pas de clé étrangère enfant

Voir l'exemple de code ci-dessous. S'il vous plaît donnez votre avis.

classe Fichiers

public class PARENT { 
    private readonly IList<CHILD> _children = new List<CHILD>(); 
    public virtual Id { get; set; } 
    public virtual void AddChild(CHILD child) { 
     _children.add(child); 
    } 
} 
public class CHILD { 
    public virtual Id { get; set; } 
} 

Mappages

<class name="PARENT" table="Parent"> 
    <cache usage="read-write"/> 

    <id name="Id" column="Id" unsaved-value="0" > 
    <generator class="identity" /> 
    </id> 

    <bag name="Children" access="field.camelcase-underscore" cascade="all-delete-orphan"> 
    <key column="ParentId"/> 
    <one-to-many class="CHILD"/> 
    </bag> 

</class> 
<class name="CHILD" table="Child"> 
    <cache usage="read-write"/> 

    <id name="Id" column="Id" unsaved-value="0" > 
    <generator class="identity"/> 
    </id> 

</class> 
+0

ne sais pas si vous savez mais, allez ici -> http://www.summerofnhibernate.com/ pour de très bons screencasts sur NHibernate! – Perpetualcoder

Répondre

2

Vous devez définir les deux côtés de la relation dans votre cartographie et le modèle d'objet. Vous en déclarez alors un inverse="true" dans le mappage. Donc, quelque chose comme cela devrait fonctionner:

fichiers de classe

public class PARENT { 
    private readonly IList<CHILD> _children = new List<CHILD>(); 
    public virtual Id { get; set; } 
    public virtual void AddChild(CHILD child) { 
     _children.add(child); 
    } 
} 
public class CHILD { 
    public virtual PARENT Parent { get; set; } 
    public virtual Id { get; set; } 
} 

Mappages

<class name="PARENT" table="Parent"> 
    <cache usage="read-write"/> 

    <id name="Id" column="Id" unsaved-value="0" > 
    <generator class="identity" /> 
    </id> 

    <bag name="Children" access="field.camelcase-underscore" 
    cascade="all-delete-orphan" inverse="true"> 
    <key column="ParentId"/> 
    <one-to-many class="CHILD"/> 
    </bag> 

</class> 
<class name="CHILD" table="Child"> 
    <cache usage="read-write"/> 

    <id name="Id" column="Id" unsaved-value="0" > 
    <generator class="identity"/> 
    </id> 
    <many-to-one name="Parent" class="PARENT" column="ParentId" /> 

</class> 

Et vous voudrez peut-être changer votre méthode AddChild à ceci:

public virtual void AddChild(CHILD child) { 
    _children.add(child); 
    child.Parent = this; 
} 
+0

Merci de votre réponse! pour le mappage CHILD, "class" n'est pas un attribut valide pour "property". J'ai essayé de le supprimer, mais il ne peut pas déterminer Type pour PARENT. J'ai également essayé de changer "propriété" à "plusieurs-à-un", mais cela a abouti à mon erreur précédente d'essayer d'insérer une clé étrangère nulle. –

+0

Désolé, était hors de ma tête. Éditera poste. –

+0

Cela fonctionne, mais j'ai toujours "Impossible d'insérer la valeur NULL dans PARENT_ID". Mes étapes sont, créer PARENT, persister PARENT, flush, Ajouter enfant à PARENT, persister PARENT, Erreur, Cri, essayer Stackoverflow. –

0

J'ai eu le même p roblem, pour l'instant je viens de supprimer les contraintes non nulles sur ce type de clés étrangères. Puisque la base de données est seulement utilisée avec NH, il n'est pas possible d'y obtenir des valeurs nulles.

Je pense que NHibernate stocke l'enfant en premier. Ensuite, il stocke le parent. Parce que vous avez besoin d'identifiants d'identité, il n'a pas de clé primaire pour le parent avant qu'il ne soit inséré dans la base de données. Ensuite, il doit mettre à jour l'enfant après.

Essayez un autre générateur d'ID. hilo est recommandé. C'est aussi plus rapide.

+0

Malheureusement, la base de données est utilisée par un couple de clients différents, donc je préfère maintenir cette intégrité dans la base de données directement. –

Questions connexes