I've got a simple phone directory app using Fluent NHibernate 1.1. In the app, a "Person" object has many "PhoneNumber" objects. I'm trying to delete a Person and I want to cascade deletes to PhoneNumbers. I set a convention of DefaultCascade.All()
after reading this answer. However, attempting to delete the parent object still throws an exception--it appears that NHibernate is trying to update the child table to set the parent ID to null instead of just deleting the record:
{"could not delete collection: [Person.PhoneNumbers#473][SQL: UPDATE phone_numbers SET person_id = null WHERE person_id = @p0]"}
InnerException:
{"Cannot insert the value NULL into column 'person_id', table 'directory.dbo.phone_numbers'; column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."}
My Fluent config is:
public static ISessionFactory CreateSessionFactory() {
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["activeConnStr"]].ConnectionString))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Person>()
.Conventions.Add(DefaultCascade.All())
)
.BuildSessionFactory();
}
The parent class is:
public class Person {
public Person() {
PhoneNumbers = new List<PhoneNumber>();
EmailAddresses = new List<string>();
}
public virtual int Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string Company { get; set; }
public virtual IList<PhoneNumber> PhoneNumbers { get; set; }
public virtual IList<string> EmailAddresses { get; set; }
}
The child class (PhoneNumber) is:
public class PhoneNumber {
public virtual string Number { get; set; }
public virtual PhoneNumberType NumberType { get; set; }
public virtual Person Person { get; set; }
}
My code to delete a person is:
public static void DeletePerson(int id) {
using (var session = Dalc.Instance.SessionFactory.OpenSession()) {
using (var trans = session.BeginTransaction()) {
session.Delete(session.Load<Person>(id));
trans.Commit();
}
}
}
What am I doing wrong?
I'm not sure about configuring the Fluent part, but I recently had the same problem with ActiveRecord.
You need to set your association, on the Person side, as Inverse = true
.
From looking at the Getting Started documentation...
I belive, you need to set this when defining your HasMany relationship in Person. It should look something like this:
public PersonMap()
{
//<...SNIP...>
HasMany(x => x.PhoneNumbers)
.Inverse();
//<...SNIP...>
}
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