One-to-one Mapping issue with NHibernate/Fluent: Foreign Key not updateing
- by Trevor
Summary: Parent and Child class. One to one relationship between the Parent and Child. Parent has a FK property which references the primary key of the Child. Code as follows:
public class NHTestParent
{
public virtual Guid NHTestParentId { get; set; }
public virtual Guid ChildId
{
get
{
return ChildRef.NHTestChildId;
}
set { }
}
public virtual string ParentName { get; set; }
protected NHTestChild _childRef;
public virtual NHTestChild ChildRef
{
get
{
if (_childRef == null)
_childRef = new NHTestChild();
return _childRef;
}
set
{
_childRef = value;
}
}
}
public class NHTestChild
{
public virtual Guid NHTestChildId { get; set; }
public virtual string ChildName { get; set; }
}
With the following Fluent mappings:
Parent Mapping
Id(x => x.NHTestParentId);
Map(x => x.ParentName);
Map(x => x.ChildId);
References(x => x.ChildRef, "ChildId").Cascade.All();
Child Mapping:
Id(x => x.NHTestChildId);
Map(x => x.ChildName);
If I do something like (pseudo code) ...
HTestParent parent = new NHTestParent();
parent.ParentName = "Parent 1";
parent.ChildRef.ChildName = "Child 1";
nhibernateSession.SaveOrUpdate(aParent);
Commit;
... I get an error: "Invalid index 3 for this SqlParameterCollection with Count=3"
If I change the parent 'References' line as follows (i.e. provide the name of the child property I'm pointing at):
References(x => x.ChildRef, "ChildId").PropertyRef("NHTestChildId").Cascade.All();
I get the error: "Unable to resolve property: NHTestChildId"
So, I tried the 'HasOne()' reference setting, as follows:
HasOne<NHTestChild>(x => x.ChildRef).ForeignKey("ChildId").Cascade.All().Fetch.Join();
This results in the save working, but the load fails to find the child. If I inspect the SQL Nhibernate produces I can see that NHibernate is assuming the Primary key of the parent is the link to the child (i.e. load join condition is "parent.NHTestParentId = child.NHTestChildId). The 'ForeignKey' specified appears to be ignored. I can set any value and no error occurs - the join just always fails and no child is returned.
I've tried a number of slight variations on the above. It seems like it should be a simple thing to achieve. Any ideas?