I have 2 tables with manyToMany relationship. user can have many groups and groups can have many users.
public class User
{
public virtual Guid Id { get; set; }
public virtual UInt64 UserId { get; set; }
public virtual IList<Group> Groups{ get; set; }
}
public class Group
{
public virtual Guid Id { get; set; }
public virtual Guid GroupGuid { get; set; }
}
I use Fluent NHibernate to AutoMap them as follows:
.Override<User>(obj => obj.HasManyToMany(x => x.Groups).Table("UserToGroup").Cascade.AllDeleteOrphan())
As a result Nhibernate produce 3 tables: 1. Users - Mapped object table 2. Groups Mapped Object table 3. UserToGroup - generated association table
The requirement is to have the following functionality on these tables: 1. AddUser(UInt64 UserId, IEnumerable groups) 2. RemoveGroup(GroupGuid groupGuild) 3. Dictionary> GetGroupToUsers();
AddUser method is work Ok, All table updated OK: * Insert of new user in User table. OK * Insert of new group in Group table. OK * Insert of new relations recods in UserToGroup table. OK
I use the following code to add a User (including groups):
public void AddUser(User userData, IList<Guid> groupIds)
{
User user = new User();
user.UserId = userData.UserId;
IList<User> Users = new List<Users();
Users.Add(user);
IList<Group> groups = new List<Group>();
foreach (Guid groupId in groupIds)
{
Group grp = new Group();
grp.GroupGuid = groupId;
grp.Users = Users;
groups.Add(grp);
}
user.Groups = groups;
Session.Save(user);
}
I use the following code to Remove group:
public void RemoveGroup(GroupGuid groupGuild)
{
IList<Group> groupsToRemove = Session.QueryOver<Group>().Where(
row => row.GroupGuid == groupGuild).List();
foreach (Group group in groupsToRemove)
{
group.Users.Clear();
Session.Delete(group);
}
}
RemoveGroup method failed with the following exception:
threw exception:
NHibernate.Exceptions.GenericADOException: could not delete: [StorageObject.Group#11111111-1111-1111-1111-111111111111][SQL: DELETE FROM "Group" WHERE Id = ?] ---> System.Data.SqlServerCe.SqlCeException: The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = FK4B29424018FA0CD4 ]
I understand that Group table can't be delete since the reference UserToGroup table point to Group table.
- 1st question: how can I make hibernate to understand that I want to be able to controller this manyToMany relation from both side: Add users with groups - from user side. And delete groups - from group side
I tried to move Inverse to the User table but in this case when I add a User the association table is not populate.
What is the best way to define this kind of manyToMany relation?
Update: Another way I tried is to have List of Users also in Groups in this configuration removeGroup is wokring but addUser in not working for specific scenario:
public class Group
{
public virtual Guid Id { get; set; }
public virtual Guid GroupGuid { get; set; }
public virtual IList<User> Users{ get; set; }
}
public class User
{
public virtual Guid Id { get; set; }
public virtual UInt64 UserId { get; set; }
public virtual IList<Group> Groups{ get; set; }
}
Now I have a bidirectional many to many. My Fluent mapping is:
.Override<User>(obj => obj.HasManyToMany(x => x.Groups).ParentKeyColumn("UserId").ChildKeyColumn("GroupId").Table("UserToGroup").Cascade.SaveUpdate()
.Override<Group>(obj => obj.HasManyToMany(x => x.Users).ParentKeyColumn("GroupId").ChildKeyColumn("UserId").Table("UserToGroup")
If I use this configuration RemoveGroup works fine but AddUser is not working for the following case: When adding 2 Users which contains the same Group the association table delete the first relation and holds just the last reference instead of having both relations. Please advise.