views:

23

answers:

1

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 Users. Roles are shared, i.e. all admin Users 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 Users, one for Roles 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.

+1  A: 

My first gut reaction is that you don't want cascade="save-update" on the Roles collection off the User.

You'd only want that, if you want changes you make to the actual Roles to be saved/updated when you save the User.

I assume what you were going after was making sure the relationship saves, but that happens regardless of your cascade setting.

CubanX