I have a Car entity which possesses doors. When the car is deleted, the doors should be deleted too because they don't make sense on their own. Here's the mapping in FluentNHibernate.
public class CarMap : ClassMap<Car>
{
public CarMap()
{
Id(x => x.CarId).GeneratedBy.Assigned();
HasMany(x => x.Doors).Cascade.AllDeleteOrphan();
}
}
public class DoorMap : ClassMap<Door>
{
public DoorMap()
{
Id(x => x.DoorId);
References(x => x.Car);
}
}
The Delete method inside the CarDao looks like :
public void Delete(Car car)
{
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
session.Delete(car);
transaction.Commit();
}
}
However, when deleting a car this way, the doors are not deleted, but the carId is put de NULL. I thought that the Cascade.AllDeleteOrphan(), would take care of deleting the children (Doors). I had to rework the Delete method to this:
public void Delete(Car car)
{
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
var entity = session.Get<Car>(car.CarId);
if (entity != null)
{
session.Delete(entity);
transaction.Commit();
}
}
}
I feel like there is something I'm missing here, because it doesn't feel right to have to get an object before deleting it. Any thoughts?
You are instantiating and disposing of a session on each request. In your first Delete method the instantiated session is not the same session that originally loaded the Car object you are passing in. It therefore has no reference to the Door objects in order to delete them when you request the deletion of the Car.
In your second method the session loads the Car and so has reference to the child objects (even if the child objects are not fully loaded nHibernate will load a proxy), this allows that session to cascade the delete through to the door objects when you delete the car.
Depending on your application a Session should be spun up at a higher level and used across multiple transactions. It is an unnecessary overhead to create and dispose of a Session for each and every transaction.
I would recommend you take a read of the following post about session management in nHibernate:
http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx