NHibernate many-to-many
relation does provide what we expect, let me explain it in more details. While we need only two entities User and Group, we will need Three tables: User
, Group
, UserGroup
(with columns UserId, GroupId)
C# entities:
public class User {
IList<Group> Groups {get;set;}
}
public class Group{
IList<User> Users{get;set;}
}
hbm.xml our mapping will look like this:
<class name="User" ...
<bag name="Groups" lazy="true"
table="UserGroup" cascade="none" >
<key column="UserId" />
<many-to-many class="Group" column="GroupId" />
</bag>
...
<!-- and group vica versa -->
<class name="Group" ...
<bag name="Users" lazy="true"
table="UserGroup" cascade="none" >
<key column="GroupId" />
<many-to-many class="User" column="UserId" />
</bag>
...
This mapping with important setting cascade="none"
will do expected behaviour. This mapping says that there is a PairTable UserGroup
, which does not have any entity representation. So, there cannot be any cascade setting effecting this table. This table is used hiddenly behind the scene.
Pair table
When some user is deleted, then NHibernate will aslo remove all the relations from the UserGroup
table (in fact this will be the first statement in the batch). This is just the relational reference constraint handling. We cannot leave any UserId
in the table UserGroups
, which does not have its foreign key in the User
table.
The other relation end
Finally the cascade setting: Because the UserGroup
table is managed without any our attention, the cascade is in this case applied to entity Group
- the other relation end. So setting it to all-delete-orphan could lead to complete deletion of all cross referenced records.
Summary: cascade on a bag
with many-to-many
relation is meant for the other end point, not the pairing table.