1

I have a class with some properties and a collection of names like so:

public class A : BaseObject
{
    private Int32 zindex;
    private Int32 atNmNr;
    private IList<G020_Namen> names = new List<G020_Namen>();
}

Then I have a class B that extends class A like so:

public class B : A
{
    private Int32 zindex;
    private String etiketnaam;

    public B() { }

    public virtual Int32 Zindex
    {
        get { return zindex; }
        set { zindex = value; }
    }
}

A and B are linked on their primary keys. Class B is mapped in the mapping file of class A as a joined-subclass like so:

    <class name="A" table="A" lazy="true" >
<cache usage="read-write"/>
<id name="Zindex" type="Int32" >
  <column name="Zindex" />
  <generator class="assigned" />
</id>
<property name="AtNmNr" type="Int32">
  <column name="ATNMNR"/>
</property>
<bag name="Namen" table="G020_Namen" inverse="true" cascade="all-delete-orphan" fetch="select" lazy="false" >
  <cache usage="read-write"/>
  <key>
    <column name="NMNR" />
  </key>
  <one-to-many class="G020_Namen" />
</bag>
<joined-subclass name="B" table="B" >
  <key column="Zindex" />
  <property name="Zindex" type="Int32">
    <column name="Zindex"/>
  </property>
  <property name="Etiketnaam" type="String">
    <column name="Etiketnaam"/>
  </property>
</joined-subclass>

Now if I want to retrieve records for A using Criteria it works fine and the collection of names is loaded. But if I want to retrieve records for the subclass B the collection of names is not loaded (on the base class A).

I then tried to add a CreateCriteria to map the collection:

        ICriteria crit = session.CreateCriteria(typeof(B))
            .CreateCriteria("Names", NHibernate.SqlCommand.JoinType.InnerJoin);

It results in the following SQL:

SELECT B.Zindex, B.Etiketnaam, G020_Namen.NMNAAM FROM B
INNER JOIN A ON B.Zindex = A.Zindex 
INNER JOIN G020_Namen ON B.Zindex = G020_Namen.NMNR

So it is trying to link the table with the names to the primary key of the subclass table B instead of to the foreign key of the base table A. It should be:

SELECT B.Zindex, B.Etiketnaam, G020_Namen.NMNAAM FROM B
INNER JOIN A ON B.Zindex = A.Zindex 
INNER JOIN G020_Namen ON A.AtNnNr = G020_Namen.NMNR

The question is: Is it possible to make NHibernate load a collection on a base class from the subclass with ICriteria statements?

Thanks,

Martin van der Linden.

1 Answers1

0

Your expectation are incorrect:

INNER JOIN G020_Namen ON A.AtNnNr = G020_Namen.NMNR

AtNnNr is not even mapped. If you meant ATNMNR than it should not be used in join because it is a simple column without FK. Please add more information on the original problem:

But if I want to retrieve records for the subclass B the collection of names is not loaded (on the base class A).

What is not loaded? Names or Bs? Not loaded how? Exception or empty collection?

As a side note, your mapping is not optimal.

  • Looks like you want your collection to be loaded eagerly (lazy="false"). In this case, use fetch="join" instead of fetch="select" to avoid additional SELECT.

  • You don't need <property name="Zindex" type="Int32"> on class B. You can get this from the base class if you make zindex protected.

Dmitry
  • 17,078
  • 2
  • 44
  • 70
  • Thank you very much for your help. Your remark that AtMnNr is not mapped as a foreign key was the solution. After mapping AtMnNr as Nhibernate was able to find the table with names correctly. – Martin van der Linden Sep 15 '11 at 08:25