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