2009-02-03 6 views
1

je reçois l'erreur suivante lors d'une tentative d'utiliser NHibernate persister une nouvelle instance de 2 objets qui ont plus d'une association entre eux:applications NHibernate pour 2 classes qui ont des relations multiples

NHibernate.Exceptions.GenericADOException: could not insert: [MyProject.BusinessEntities.Client][SQL: INSERT INTO dbo.Client (Version, CurrentEvent_ClientEvent_Id, EntityType, Id) VALUES (?, ?, 'MyProject.BusinessEntities.Client', ?)] ---> System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK328F067A46E318FD". The conflict occurred in database "DatabaseName", table "dbo.ClientEvent", column 'ClientId'. 

Le scénario est comme suit:

J'ai 2 classes (que j'ai renommé pour plus de clarté): Client et ClientEvent. Le client a une propriété appelée Events qui est de type List. ClientEvent contient une propriété "Client" qui est l'association inverse à l'objet Client. En outre, la classe Client possède une autre propriété appelée CurrentEvent, qui contient une référence à l'un des éléments de la collection ClientEvents.

Client.hbm.xml contient:

<bag name="ClientEvents" access="field.camelcase-underscore" inverse="true" cascade="save-update"> 
    <key column="Client_Id"/> 
    <one-to-many class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" /> 
</bag> 
<many-to-one name="CurrentEvent" access="property" class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" column="CurrentEvent_ClientEvent_Id" cascade="save-update" /> 

ClientStatusRecord.hbm.xml contient:

<many-to-one name="Client" access="property" class="MyProject.BusinessEntities.Client, MyProject.BusinessEntities" column="Client_Id" cascade="save-update" /> 

I générer automatiquement le schéma de base de données à partir des correspondances, et les clés étrangères dans les deux tables sont tous les deux nullables.

J'utilise le code suivant pour persister un nouveau client et ClientRecord (encore une fois simplifiée pour éliminer toute la gestion de la session gumpf)

var newClient = CreateNewClient(); 
var newEvent = CreateNewEvent(); 
newEvent.client = newClient; // ensure the reverse association is set 
newClient.Events.Add(newEvent); 
session.SaveOrUpdate(newClient); 
session.Flush(); 

Avoir un oeil à la sortie de SQL à partir NHibernate, il semble essayer de sauvegarder l'enregistrement du client avant d'enregistrer le record ClientEvent, en essayant d'insérer l'ID ClientEvent dans la clé étrangère qui échoue parce que le dossier de ClientEvent n'existe pas encore

questions

  • Quelqu'un at-il obtenu de travailler où nhibernate persiste objet avec de multiples relations?
  • Si oui, à quoi devraient ressembler les mappages?
  • Des suggestions de choses que je peux essayer?

Désolé pour le poste éternise

Répondre

3

Merci, j'ai essayé toutes les combinaisons de définir la propriété cascade à Save-Update ou None dans les mappages Client et ClientEvent, mais sans Succès. Cependant, en construisant mes mappages étape par étape à partir de zéro, j'ai compris quel était le problème ... Je fixais l'ID sur les objets Client et ClientEvent plutôt que de laisser NHibernate générer des valeurs au moment où les objets sont persistés. Dans la plupart des cas, il ne semble pas important si vous définissez explicitement l'Id avant de persister les objets. Cependant, dans ce cas, il semble que NHibernate résout incorrectement l'ordre dans lequel les objets doivent persister et tente de conserver un enregistrement Client référençant un EventClient qui n'existe pas déjà.

Solution: Soit NHibernate générer l'identifiant pour les objets

0

Je suppose qu'il est à propos cascade, essayez de changer les valeurs des cascades dans les applications. Pas sûr à 100% mais, essayez de mettre les cascades à "aucun" dans plusieurs mappings

Questions connexes