1
votes

I'm trying to get NHibernate (3.3.1) to load a recursive parent/child category relationship.

public class Category 
{
    public virtual int Id { get; set; }

    public virtual bool IsActive { get; set; }

    public virtual string Name { get; set; }

    public virtual Category Parent { get; set; }

    public virtual IList<Category> Children { get; set; }

    public Category()
    {
        Children = new List<Category>();
    }

    public virtual int GetChildCount()
    {
        return Children.Count;
    }
}

And my XML Mapping...

 <class name="nHibernatePOC.Domain.Category, nHibernatePOC" lazy="true">
    <id name="Id" column="CategoryId">
      <generator class="identity" />
    </id>
    <property name="Name" column="Name" />
    <property name="IsActive" column="IsActive" />
    <many-to-one name="Parent" class="nHibernatePOC.Domain.Category" column="ParentCategoryId" /> 

    <bag lazy="true" name="Children">
      <key column="ParentCategoryId" />
      <one-to-many class="nHibernatePOC.Domain.Category" />
      <loader query-ref="GetCategoryByParentId"/>
    </bag> 
  </class>

My issue is when I try to access Children.Count I get a NullReferenceException because the Parent can be null.

1
Children shouldn't be null because it will be initialized to an empty collection if no children are found. Could the <loader query-ref= be the problem. Do you really need that or can you use a formula on the key? - Firo
I may have forgot to mention that the NullReferenceException is in regards to the Parent property, the children is initialised with an empty collection. Also the loader is required since the data comes from stored procedures not direct table mappings. - Sam Lad
can you show the code which saves the categories? Also when you have a backreference (Parent property) you should mark the collection as inverse to not double insert the parentId - Firo

1 Answers

0
votes

For future reference, the problem was related to the stored procedure that was used to load the child collection. (Rather than lazy loading from a table / view). Thankfully I am in a position to load from a view instead of using a Stored Procedure.

The moment I removed the <loader element and reverted to using a view from the database (MSSQL 2012) it worked as expected.

Very odd, sorry to anyone who needs to use stored procedures but I'm guessing it's a good reason to remove them in this case.