2008-09-28 9 views
8

Ich habe ein neues Objekt mit einer Sammlung neuer Objekte darin auf einer Eigenschaft als IList. Ich sehe durch SQL Profiler zwei Insert-Abfragen ausgeführt werden .. eine für die Eltern, die die neue GUID-ID hat, und eine für das Kind, jedoch der Fremdschlüssel auf das Kind, das auf die Eltern verweist, ist eine leere GUID. Hier ist meine Zuordnung auf dem parent:Warum legt meine NHibernate-Taschenkollektion die Eltern-ID der Kinder nicht dynamisch fest?

<id name="BackerId"> 
    <generator class="guid" /> 
</id> 
<property name="Name" /> 
<property name="PostCardSizeId" /> 
<property name="ItemNumber" /> 

<bag name="BackerEntries" table="BackerEntry" cascade="all" lazy="false" order-by="Priority"> 
    <key column="BackerId" /> 
    <one-to-many class="BackerEntry" /> 
</bag> 

Auf der Backer.cs Klasse I definiert BackerEntries Eigenschaft als

IList<BackerEntry> 

Wenn ich versuche, die in Einheit weitergegeben SaveOrUpdate erhalte ich die folgenden Ergebnisse in SQL Profiler:

exec sp_executesql N'INSERT INTO Backer (Name, PostCardSizeId, ItemNumber, BackerId) VALUES (@ p0, p1 @, @ p2, p3 @) 'N' @ p0 nvarchar (3), p1 @ UNIQUE , @ p2 nvarchar (3), @ p3 eindeutige Kennung ', @ p0 = N'qaa', @ p1 = 'BC95E7EB-5EE8-44B2-82FF3 0F5176684D '@ p2 = N'qaa', @ p3 = '18FBF8CE-FD22-4D08-A3B1-63D6DFF426E5'

exec sp_executesql N'INSERT INTO BackerEntry (BackerId, BackerEntryTypeId, Name, Beschreibung MaxLength, IsRequired, Priorität , BackerEntryId) WERTE (@ p0, @ p1, @ p2, @ p3, @ p4, @ p5, @ p6, @ p7) ', N' @ p0 eindeutige Kennung, @ p1 eindeutige Kennung, @ p2 nvarchar (5), @ p3 nvarchar (5), @ p4 int, @ p5 bit, @ p6 int, @ p7 eindeutige Kennung ', @ p0 =' 00000000-0000-0000-0000-000000000000 ', @ p1 =' 2C5BDD33-5DD3-42EC-AA0E-F1E548A5F6E4 ', @ p2 = N'qaadf', @ p3 = N'wasdf ', @ p4 = 0, @ p5 = 1, @ p6 = 0, @ p7 =' FE9C4A35-6211-4E17-A75A-60CCB526F1CA '

Wie Sie sehen können, wird die leere GUID für BackerId des untergeordneten Elements nicht auf die neue echte GUID des übergeordneten Elements zurückgesetzt.

Schließlich ist die Ausnahme Wurf:

"NHibernate.Exceptions.GenericADOException: could not insert: [CB.ThePostcardCompany.MiddleTier.BackerEntry][SQL: INSERT INTO BackerEntry (BackerId, BackerEntryTypeId, Name, Description, MaxLength, IsRequired, Priority, BackerEntryId) VALUES (?, ?, ?, ?, ?, ?, ?, ?)] ---\u003e System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint 

EDIT: GELÖST! Die erste Antwort unten zeigte mir die richtige Richtung. Ich musste diese Rückreferenz für das Kind-Mapping und die Klasse hinzufügen. Dies ermöglichte, dass es auf eine rein .net-Weise funktioniert - jedoch, als ich json annahm, gab es eine Trennung, also musste ich mir einen skurrilen Code einfallen lassen, um die Kinder wieder anzubringen.

Antwort

9

Sie müssen möglicherweise NICHT-NULL = „true“, um Ihre Mapping-Klasse hinzuzufügen:

<bag name="BackerEntries" table="BackerEntry" cascade="all" lazy="false" order-by="Priority"> 
    <key column="BackerId" not-null="true"/> 
    <one-to-many class="BackerEntry" /> 
</bag> 

sowie sicherstellen, dass Sie die Rückseite des Mapping definiert für das Kind Klasse:

<many-to-one name="parent" column="PARENT_ID" not-null="true"/> 

Ich hatte ähnliche Probleme mit Hibernate auf meinem aktuellen Projekt mit Eltern-Kind-Beziehungen, und das war ein Teil der Lösung.

+0

Vielen Dank .. Sie haben mich in die richtige Richtung gezeigt ... Ich hatte nicht die Zurück-Referenz in meinem Kind Mapping. – EvilSyn

0

Ich hatte dieses Problem und es dauerte mich für immer herauszufinden. Die Child-Tabelle muss Nullen auf ihrem übergeordneten Fremdschlüssel zulassen. NHibernate speichert die untergeordneten Objekte mit NULL in der Fremdschlüsselspalte und kehrt dann zurück und aktualisiert sie mit der richtigen ParentId.

+1

Ist das wahr ??? – Dan

+1

definitiv nicht wahr, müssen Sie eine bidirektionale Zuordnung zuordnen, so dass das inverse Ende ist das übergeordnete und Eigenschaften auf beiden Seiten festlegen. http://www.nhforge.org/doc/nh/en/index.html#collections-bidirektional – dotjoe

+0

+1. Ja, das stimmt. Die FK-Spalte in der untergeordneten Tabelle muss nullbar sein, damit dies funktioniert.NHibernate fügt das untergeordnete Element mit ParentID-Satz zu NULL hinzu und aktualisiert dann die ParentID, wenn Parent tatsächlich in der Datenbank gespeichert wird. –