Search code examples
c#nhibernateormmany-to-manynhibernate-mapping

NHibernate Many-to-Many with same class


Apologies if this has been answered previously. i've tried google but could not find an answer.

At the moment i have a class

public class User
{
    public virtual string Username { get; set; }
    public virtual string Name { get; set; }

    public virtual ISet<User> Teamleaders { get; set;}
    public virtual ISet<User> Staff { get; set;}
}

teamLeaders stores all the teamleaders that this one user has. staff stores all the staff that a teamleader has.

This is a Many to Many relationship.

currently my XML file is as shown below

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="SDReward"
               namespace="SDReward.Domain">
  <class name="User">
    <id name="Username" />
    <property name="Name" />

  </class>
</hibernate-mapping>

I have got it working with the following data. it grabs data from the teamleaderstaff table

<set name="Teamleaders" table="teamleaderstaff">
  <key column="TeamleaderId" />
  <many-to-many column="UserId" class="User" />
</set>

<set name="Staff" table="teamleaderstaff">
  <key column="UserId" />
  <many-to-many column="TeamleaderId" class="User" />
</set>

But when i do an insert it inserts them in to the database double... for example if i add 1 team leader to a user and add that user as staff of the team leader it makes 2 inserts both with same data.


Solution

  • Mapping of many-to-many in your case could look like

    <set name="Teamleaders" table="teamleaderstaff" lazy="true">
      <key column="UserId"/>
      <many-to-many class="User" column="TeamleaderId"/>
    </set>
    
    
    <set name="Staff" table="teamleaderstaff" lazy="true" inverse="true" >
      <key column="TeamleaderId"/>
      <many-to-many class="User" column="UserId"/>
    </set>
    

    1) The difference is in the <key column mapping.

    2) During the insert, one of the collections (Staff) is marked as inverse="true", so it won't trigger double inserts