hey there
Trying to implement relatively simple relationship between User
and Role
. User
can be in many roles, same Role
can belong to any number of User
s. Role
s are shared, i.e. all admin User
s refer to the very same instance of class Role
.
User
mapping:
<class name="User" lazy="false" table="Users">
<id name="Id" type="int">
<generator class="native"/>
</id>
<property name="Name" column="Username" />
<bag name="RoleList" table="User_Role" inverse="true" lazy="false" cascade="save-update">
<key column="UserId" foreign-key="Id"/>
<many-to-many class="Role" column="RoleId"/>
</bag>
</class>
Role
mapping:
<class name="Role" lazy="false" table="Roles">
<id name="Id" type="int">
<generator class="native"/>
</id>
<property name="Name" column="Rolename"/>
<property name="Description"/>
</class>
There are three DB tables: one for User
s, one for Role
s and the third is for the many-to-many relation (with two foreign keys: UserId
and RoleId
). A primary key is the composite key of those two.
The problematic scenario: the roles are predefined. In my C# code I am constructing a user, while attaching the role to it. The role is an object that was successfully fetched from DB with correct id. I am trying to save that user in the database.
Now to the question: I am receiving a duplicate key DB error, since NHibernate is trying to insert the Role
object into the appropriate table. Since the RoleId
already belongs to the existing role, I would expect that no new role will be inserted in DB.
Gory details: I've also tried to debug the NHibernate and seen that for some reason EntityIdentityInsertAction
receives a Role
and calls base constructor. In the call to the base constructor the Id
parameter is a simple hard-coded null. The stack trace also contains a call to SaveWithGeneratedId()
(somewhere earlier in the chain), which implies that the Id
for the existing Role
object is not counted for some reason.
This is all the info I've succeeded to find so far. Please tell what am I doing wrong.