I have a bidirectional association like this:
public class Parent
{
public int ParentId {get; set;}
...other properties
public IEnumerable<Child> Children {get; set;}
}
public class Child
{
public int ChildId {get; set;}
...other properties
public Parent Parent {get; set;}
}
The fluent mappings are as follows:
Parent mapping
Id(x => x.ParentId, "PARENT_ID").GeneratedBy.Identity();
.. other mappings
HasMany(x => x.Children).Cascade.All().KeyColumn("PARENT_ID");
Child mapping
Id(x => x.ChildId, "CHILD_ID").GeneratedBy.Identity();
.. other mappings
References(x => x.Parent).Column("PARENT_ID").Cascade.None();
When I execute code like this:
Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);
I get a foreign key constraint violation because NHibernate is not setting the PARENT_ID
column of the child record to the new ID when it attempts to insert the child.
Clearly I have requested cascading in the mapping for Parent
. NHibernate is trying to save the child, but why is the ID not being set?
You need to make two changes.
.Inverse()
on the HasMany(x => x.Children)
. See my answer explaining inverse for more information.child.Parent = parent;
to the code that saves the entities.In your case, the two relationships are conflicting with one another. parent.Children
contains child
, which means that NHibernate should persist Child.PARENT_ID
as the parent's Id, but child.Parent
is null, meaning that NHibernate should persist Child.PARENT_ID
as null. Apparently child.Parent
won. Actually, what's more likely is that they both won. NHibernate was probably executing two queries similar to these...
/* This is what child.Parent says we should save.
This query will fail because PARENT_ID is NOT NULL. */
insert into Child (CHILD_ID, PARENT_ID) values (@childId, null);
/* This is what parent.Children says we should save. */
update Child set PARENT_ID = @parentId where CHILD_ID = @childId;
If you make the two changes I recommend above, NHibernate will be able to save this correctly, like so:
insert into Child (CHILD_ID, PARENT_ID) values (@childId, @parentId);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With