I have a code that was working perfectly on NHibernate 3.1, but when it is not working on NHibernate 4.0
So, this is the class relations
public class Employee : BaseEntity
{
...
public Department Dept { get; set; }
}
public class Department : BaseEntity
{
...
public IList<Employee> Employees { get; set; }
}
and for the mapping we have this
DepartmentMap : ClassMap<Department>
{
Table("....");
HasMany(x => x.Employees).KeyColumn("DeptId").Not.KeyNullable();
}
EmployeeMap : ClassMap<Employee>
{
Reference(x => x.Dept).Column("DeptId");
}
and when I am adding an employee like that
var dept = session.Load<Department>(deptId);
newEmployee.Dept = dept;
session.Save(newEmployee);
But it is throwing an error:
NHibernate.PropertyValueException: not-null property references a null or transient value
I read that I have to add the relation in two ways, so I modified it to this
var dept = session.Load<Department>(deptId);
newEmployee.Dept = dept;
dept.Employees.Add(newEmployee);
session.Save(newEmployee);
But now I have this error :
NHibernate.PropertyValueException: Error dehydrating property value for... System.IndexOutOfRangeException: Invalid index 7 for this SqlParameterCollection with Count=7.
So, I want to know how to fix it and where I can read about the changes in NHibernate about this with bi-direction
First issue - bi-directional mapping
We should always assign both sides of relation. Well, always?!? This is the perferred and good practice.
But in case, that we want to use
.Load()
to retrieveparent
(Department) - we should not need assignparent.Chidren.Add()
.The
Load()
is smart way how to get "fake" (proxy) instance, represented just by ID of that entity (engough to create proper INSERT statement)So, in this case we should avoid
dept.Employees.Add(newEmployee);
- we do not need to load Department at allSecond (real) issue - double mapping
While it is not visible in the question code snippets, I would bet, that Employee in fact has this def and mapping
So - we have two properties in C# which belongs to one SQL Column. I would say, it is absolutely ok, but we have to be sure that we adjust that a bit. The integer should be nullable and MUST be readonly
So what happened? what are both exceptions experienced aboout?
the above issue means NHibernate expected property DeptId to be also provided
this kind of issue is usually about doubled mapping - two properties to ONE column. Most often becuase of Reference and reference id being mapped to one column...
Even if the issue is not directly with
int? DeptId
- I hope that this give you enough information to reveal the real culprit.I found the fix for the problem: The fix for the problem is to add Inverse to the mapping of the parent file. So, the mapping for Department will be: