NHibernate, collection with composite-id.

In the previous post we saw how to map an entity with a composite-id.

Well but now if you have mapped an entity in this way and you need to create a collection of this entity or maybe you have a related child class that uses this primary keys … you are in trouble! Smile

The way to solve the problem is very easy. First of a short example to understand what I’m talking about:

   1: class Foo {

   2:     public string name { get; set; }

   3:     public string lastname { get; set; }

   4:     public IList<childfoo> listofchild { get; set; }

   5: }

   6: class childfoo {

   7:     public string name { get; set; }

   8:     public string lastname { get; set; }

   9:     public Foo father { get; set; }

  10: }

Now the first class will be mapped in this way if we assume that “name and lastname are the primary keys”. (Also remember to override Equals() and GetHashCode()!!).

   1: <class name="Foo" table="[Foo]" schema="xxx">

   2:   <composite-id>

   3:     <key-property name="name">

   4:       <column name="[name]" sql-type="varchar" length="50" not-null="true"/>

   5:     </key-property>

   6:     <key-property name="lastname">

   7:       <column name="[lastname]" sql-type="varchar" length="50" not-null="true"/>

   8:     </key-property>

   9:   </composite-id>

   1: <bag name="listofchild" table="[childfoo]" inverse="true"

   2:    cascade="all-delete-orphan" generic="true" lazy="true">

   3:   <key>

   4:     <column name="[name]" sql-type="varchar"/>

   5:     <column name="[lastname]" sql-type="varchar"/>

   6:   </key>

   7:   <one-to-many class="Foo" not-found="ignore"/>

   8: </bag>

Now we can go back to the child mapping file and reference the many-to-one foreign mapping in this simple way:

   1: <many-to-one name="Foo" lazy="proxy" not-null="false">

   2:   <column name="[name]" sql-type="varchar"/>

   3:   <column name="[lastname]" sql-type="varchar"/>

   4: </many-to-one>

So now my repository will be able to give me:


And in that moment my repository will go back and execute the sub-select.