I have a one-to-one relationship between a Person class and an Employee. I expect the INSERT to cascade from the Person to the Employee. However, this does not happen. I've tried cascade='all' and cascade='save-update' on one-to-one relationship element, but it didn't work.
The structures of the my objects are as follows:
public class Person
{
public virtual Employee Employee { get; set; }
public virtual int Age { get; set; }
public virtual string Forename { get; set; }
public virtual string Surname { get; set; }
public virtual int PersonID { get; set; }
}
public class Employee
{
public virtual int PersonID { get; set; }
public virtual string PayRollNo { get; set; }
public virtual int Holidays { get; set; }
public virtual Person Person { get; set; }
}
Mapping files shown below:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Employee, Employee.DAL" table="`Employee`" >
<id name="PersonID" column="`PersonId`" type="int">
<generator class="native" />
</id>
<property type="string" length="30" name="PayRollNo" column="`PayRollNo`" />
<property type="int" name="Holidays" column="`Holidays`" />
<one-to-one name="Person" class="Person" cascade="all"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Person, Employee.DAL" table="`Person`" >
<id name="PersonID" column="`PersonId`">
<generator class="foreign">
<param name="property" >Employee</param>
</generator>
</id>
<property type="string" name="Forename" column="`Forename`" />
<property type="string" name="Surname" column="`Surname`" />
<property type="int" name="Age" column="`Age`" />
<one-to-one name="Employee" class="Employee" constrained="true" />
</class>
</hibernate-mapping>
Code for initiating the objects and saving them:
var employee = new Employee();
employee.Person = new Person { Employee = employee };
ISessionFactory sessionFactory = (new Configuration()).Configure().BuildSessionFactory();
employee.Person.Age = 27;
employee.Person.Forename = "N";
employee.Person.Surname = "M";
employee.PayRollNo = "12";
employee.Holidays = 27;
using (var session = sessionFactory.OpenSession())
{
session.Save(employee);
}
Put the session.Save() method in a transaction. Or use the session.Flush() method after the calling the save method.
using (var trans = session.BeginTransaction())
{
try
{
trans.Begin();
session.Save(employee);
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
}
Nhibernate occasionally stores the SQL statements to synchronise the date in memory. The session.Flush() method commits the SQL to the database. This occurs by default on the transcation.Commit() method.
For more information refer to the Nhibernate documentation http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-flushing