0

I have a many to many relationship between a Team and an Employee entity.

I mapped them as following:

public class EmployeeMap : ClassMap<Employee> { public EmployeeMap() { // identifier mapping Id(p => p.Id).Column("EmployeeID"); // column mapping Map(p => p.EMail); Map(p => p.LastName); Map(p => p.FirstName); // relationship mapping HasManyToMany(m => m.Teams).Table("EmployeeTeam") .Inverse() .Cascade.All() .AsSet() .LazyLoad() .ParentKeyColumn("EmployeeID") .ChildKeyColumn("TeamID"); HasMany(p => p.LoanedItems).Cascade.SaveUpdate().KeyColumn("EmployeeId"); } } public class TeamMap : ClassMap<Team> { public TeamMap() { // identity mapping Id(p => p.Id).Column("TeamID"); // column mapping Map(p => p.Name); // relationship mapping HasManyToMany(m => m.Employees) .Table("EmployeeTeam") .LazyLoad() .Cascade.All() .AsSet() .ParentKeyColumn("TeamID") .ChildKeyColumn("EmployeeID"); } } 

Then I created 3 Teams and 2 Employees:

TeamID EmployeeID 1 1 1 2 2 2 3 1 

The Employee1 has also 2 LoanedItems(Books, Magazines). Employee2 has no LoanedItems.

Now I want to delete Employee1, who is in Team1 and Team3. In Team 1 is also Employee2. So when I delete Employee1, I assume that Employee1 is deleted and also Team3, because I also assume that an Team can only exist when it has an Employe and vice versa. So Team1 may not be deleted, because it has Employee2 and can still exists.

I used the following code lines with a new Session:

var loadedEmployee = session.Get<Employee>(1); session.Delete(loadedEmployee); transaction.Commit(); 

But what happens? -> NHibernate deletes all Teams and all Employees! -> NHibernate updated my LoanedItem table correctly by setting the FK EmployeeID to NULL.

What is wrong there?

2 Answers 2

1

I have answered a similar question here: What is the correct way to define many-to-many relationships in NHibernate to allow deletes but avoiding duplicate records

Reading the question and my answer maybe will help you understand what is going on with your many-to-many association.

Sign up to request clarification or add additional context in comments.

4 Comments

so If I get you right, it is recommended to split a many to many association into a many to one / one to many relationship, right?
Well, as far as I've read it's always a good practice to split a many-to-many association to 2 one-to-many associations with the X table. I cannot say that it is recommended though. When it comes to handling save and delete operations on a many-to-many associations with cascades, I've found that spliting the association just gives more flexibility and control on what you can do but it adds more configuration. Maybe someone out there knows how to configure with NHibernate a many-to-many association and provide all the flexibility that one wants with save and delete operations through cascading.
I ask myself, why NH does not create an internal relationship entity for a many to many relation ... so finally you can say that you have to split your many to many assoication into 2 one to many assocations as you mentioned, because you can only give the responsiblity to one site of your association.
Mark it as duplicate or proper answer it.
1

Because of the Cascade.All on the HasManyToMany mapping.

Use Cascade.SaveAndUpdate instead, if you wish to avoid the delete cascade action.

2 Comments

When I set both ends to SaveAndUpdate the following error occurs: {"The DELETE statement conflicted with the REFERENCE constraint \"FKDA36D134BC587C57\". The conflict occurred in database \"Ariha\", table \"dbo.EmployeeTeam\", column 'EmployeeID'.\r\nThe statement has been terminated."}
that's because Employee is inverse. Which make the other end of the relationship responsible for the link. So when you try to delete Employee NH will try to insert null into EmployeeTeam and that's why {"The DELETE statement conflicted with the REFERENCE constraint \"FKDA36D134BC587C57\"... So give it a try without inverse on Employee. Or you will have to delete the link from the other end of the relationship as well. Like TeamMap.Employees.Delete(employee) Cheers

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.