Reputation: 12441
I have a Employer object that can have multiple People:
//entities
public class Person {
public virtual Guid Id {get;set;}
public virtual string Name {get;set;}
public virtual Employer CurrentEmployer {get;set;}
}
public class Employer {
public virtual Guid Id {get;set;}
public virtual string Name {get;set}
public virtual IList<Person> Employees {get;set;}
}
//person to employer mappings
References(x => x.CurrentEmployer)
.Cascade.All()
.Column("CurrentEmployerId")
.ForeignKey("FK_Person_CurrentEmployer");
//employer to person mappings
HasMany(x=> x.Employees)
.Inverse()
.Cascade.All();
When I try to delete an employer that is linked to a person, I get a "Foreign Key violation" error.
//example
_session.Delete(oldEmployer);
How do I get nHibernate to null the CurrentEmployerId column before the employer is deleted?
Upvotes: 2
Views: 1095
Reputation: 8805
Oracle has the cascading delete feature (based on foreign key constraints) built in. Sybase does not. Depending on if your database supports before and after triggers you can create the functionality with before triggers. Sybase 12 doesn't have this, it only has after triggers so it's impossible on sybase. Sybase 15 has before triggers but I haven't tried it yet, but it should work, basically you write the before trigger manually to do the cascading delete.
If this before trigger functionality doesn't exist in your database, this is not possible. You would have to programmatically delete the child table rows first before deleting the parents.
That's just how it is.
Upvotes: 0
Reputation: 3212
Try to do this one
//employer to person mappings
HasMany(x=> x.Employees)
.Inverse()
.Cascade.AllDeleteOrphan();
I didn't check it, but I hope it could help you.
Upvotes: 0
Reputation: 114846
try clearing all CurrentEmployer's first then deleting the Employee
public class Employer
{
public virtual Guid Id {get;set;}
public virtual string Name {get;set}
public virtual IList<Person> Employees {get;set;}
public void UnemployAll()
{
foreach(var employee in Employees)
{
employee.CurrentEmployer = null;
}
Employees = new List<Person>(); // clear it
}
}
then try the following (I think the employees (person) should all get updated), I don't know if this will work off the top of my head, but it may get you started in the right direction.
oldEmployer.UnemployAll();
_session.Delete(oldEmplorer);
Upvotes: 1
Reputation: 32575
Do you have code scattered all around that deletes employers? I think normally you would have only one place in the code really that deletes employers, so there wouldn't really be a need to have nhibernate do this work for you; Just have a statement there that updates all referencing employees.
If you actually do have these deletes scattered all about, then you could create an Interceptor or Event Listener that watched for deletes to the table and have the interceptor/Listener update referencing employees.
Upvotes: 0