views:

19

answers:

1

Hi there,

I have these 2 objects in NHibernate forming a many to many relationship:

User:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Providers" namespace="Providers.Objects">

  <class name="User" table="Users">

    <id name="UserId" type="int">
      <generator class="native" />
    </id>

    <many-to-one name="Application" column="ApplicationId" cascade="none" />    

    <property name="UserName" type="string" />
    <property name="LoweredUserName" type="string" />
    <property name="MobileAlias" type="string" />
    <property name="IsAnonymous" type="bool" />
    <property name="LastActivityDate" type="DateTime" />

    <bag name="Roles" table="UsersInRoles" lazy="true" cascade="none" >
      <key column="UserId"></key>
      <many-to-many class="Role" column="RoleId"></many-to-many>
    </bag>

  </class>

</hibernate-mapping>

And Role:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Providers" namespace="Providers.Objects">

  <class name="Role" table="Roles">

    <id name="RoleId" type="int">
      <generator class="native" />
    </id>

    <many-to-one name="Application" column="ApplicationId" class="Application" cascade="none" />    

    <property name="RoleName" type="string" />
    <property name="LoweredRoleName" type="string" />
    <property name="Description" type="string" />

    <bag name="Users" table="UsersInRoles" lazy="true" inverse="true" cascade="none" >
      <key column="RoleId"></key>
      <many-to-many class="User" column="UserId"></many-to-many>
    </bag>

  </class>

</hibernate-mapping>

Let's say the role backupoperator has some users in it. If I try to remove one of the users from the role instance, like:

var backupoperator = GetRoleByName(session, app.ApplicationId, "backupoperator");
backupoperator.Users.RemoveAt(0);
session.Update(backupoperator);
transaction.Commit();

It doesn't work :( The association remains unchanged in the database. When I try the opposite (remove a role from a user object and updating the user object), it works. Is it because of the inverse attribute in the NHibernate mapping?

How to accomplish what I am trying to do? (remove a user from a role, updating the role and having that persisted)?

Thanks

+1  A: 

When you write inverse="true" you are telling NHibernate that the other side maintains the relationship.

Therefore, you have to remove the Role from the User's Roles collection if you want your change persisted.

Diego Mijelshon
Thanks Diego, do you know what would be HQL command to delete a Role and remove all its associations (not remove the users, but remove the associations with the users)? I am struggling to find this. If I iterate over all users and call session.Delete on each user I'll have many round trips to the database (perhaps hundreds in some cases).
qwerty2010
You won't have so many roundtrips if you use batching, see http://nhforge.org/doc/nh/en/index.html#performance-batch-updates
Diego Mijelshon
Great, thanks for letting me know.
qwerty2010