title: NHibernate Eager Fetching Over Multiple Levels
body: <p>I have a 3-leveled hierarchy of entities: Customer-Order-Line, which I would like to retrieve in entirety for a given customer, using ISession.Get(id).  I have the following XML fragments:</p>
  
  <p>customer.hbm.xml:</p>
  
  <pre><code>&lt;bag name="Orders" cascade="all-delete-orphan" inverse="false" fetch="join"&gt;
    &lt;key column="CustomerID" /&gt;
    &lt;one-to-many class="Order" /&gt;
  &lt;/bag&gt;
  </code></pre>
  
  <p>order.hbm.xml:</p>
  
  <pre><code>&lt;bag name="Lines" cascade="all-delete-orphan" inverse="false" fetch="join"&gt;
    &lt;key column="OrderID" /&gt;
    &lt;one-to-many class="Line" /&gt;
  &lt;/bag&gt;
  </code></pre>
  
  <p>I have used the fetch="join" attribute to indicate that I want to fetch the child entities for each parent, and this has constructed the correct SQL:</p>
  
  <pre><code>SELECT 
      customer0_.ID AS ID8_2_, 
      customer0_.Name AS Name8_2_, 
      orders1_.CustomerID AS CustomerID__4_, 
      orders1_.ID AS ID4_, 
      orders1_.ID AS ID9_0_, 
      orders1_.PostalAddress AS PostalAd2_9_0_, 
      orders1_.OrderDate AS OrderDate9_0_, 
      lines2_.OrderID AS OrderID__5_, 
      lines2_.ID AS ID5_, 
      lines2_.ID AS ID10_1_, 
      lines2_.[LineNo] AS column2_10_1_, 
      lines2_.Quantity AS Quantity10_1_, 
      lines2_.ProductID AS ProductID10_1_ 
  
  FROM Customer customer0_ 
  
  LEFT JOIN [Order] orders1_ 
         ON customer0_.ID=orders1_.CustomerID 
  
  LEFT JOIN Line lines2_ 
         ON orders1_.ID=lines2_.OrderID 
  
  WHERE customer0_.ID=1
  </code></pre>
  
  <p>So far, this looks good - SQL returns the correct set of records (with only one distinct orderid), but when I run a test to confirm the correct number of entities (from NH) for Orders and Lines, I get the wrong results</p>
  
  <p>I <em>should</em> be getting (from my test data), 1xOrder and 4xLine, however, I am getting 4xOrder and 4xLine. It appears that NH is not recognising the 'repeating' group of Order information in the result set, nor correctly 'reusing' the Order entity.</p>
  
  <p>I am using all integer IDs (PKs), and I've tried implementing IComparable of T and IEquatable of T using this ID, in the hope that NH will see the equality of these entities.  I've also tried overridding Equals and GetHashCode to use the ID.  Neither of these 'attempts' have succeeded.</p>
  
  <p>Is "multiple leveled fetch" a supported operation for NH, and if so, is there an XML setting required (or some other mechanism) to support it?</p>
  
  <hr>
  
  <p>NB: I used sirocco's solution with a few changes to my own code to finally solve this one.  the xml needs to be changed from bag to set, for all collections, and the entitities themselves were changed to implement IComparable&lt;>, which is a requirement of a set for uniqueness to be established.</p>
  
  <pre><code>public class BaseEntity : IComparable&lt;BaseEntity&gt;
  {
      ...
  
      private Guid _internalID { get; set; }
      public virtual Guid ID { get; set; }
  
      public BaseEntity()
      {
          _internalID = Guid.NewGuid();
      }
  
      #region IComparable&lt;BaseEntity&gt; Members
  
      public int CompareTo( BaseEntity other )
      {
          if ( ID == Guid.Empty || other.ID == Guid.Empty )
              return _internalID.CompareTo( other._internalID );
  
          return ID.CompareTo( other.ID );
      }
  
      #endregion
  
      ...
  
   }
  </code></pre>
  
  <p>Note the use of an InternalID field.  This is required for new (transient) entities, other wise they won't have an ID initially (my model has them supplied when saved).</p>