I implement category hierarchy using the nested set model. For that a have the following <component> declaration in the Category.hbm.xml
Code:
<component name="NodeInfo" class="NHibernateHelper.NestedSet.NodeInfo, NHibernateHelper" update="true">
<parent name="Node" />
<property name="Left" type="Int64">
<column name="ns_left" sql-type="int" not-null="true" />
</property>
<property name="Right" type="Int64">
<column name="ns_right" sql-type="int" not-null="true" />
</property>
<property name="Depth" type="Int32" formula="(SELECT Count(*)
FROM Categories c
WHERE c.ns_left < ns_left AND
c.ns_right > ns_left)" />
</component>
The Category.cs has a property
Code:
public NodeInfo NodeInfo
{
get { return _nodeInfo; }
set { _nodeInfo = value; }
}
and the NodeInfo looks like:
Code:
public class NodeInfo
{
private INode _node;
private long _left = 0;
private long _right = 0;
private int _depth = 0;
public NodeInfo() { }
public NodeInfo(INode node)
{
_node = node;
}
public INode Node
{
get { return _node; }
protected internal set { _node = value; }
}
public long Left
{
get { return _left; }
protected internal set { _left = value; }
}
public long Right
{
get { return _right; }
protected internal set { _right = value; }
}
public int Depth
{
get { return _depth; }
protected internal set { _depth = value; }
}
}
When I get an instance from the database everything is OK. Left, Right and Depth are filled normally. If I try to do something like:
Code:
if (product.Category.Depth == 1) { ... }
, "Depth" has always the default value (0). It seems that in lazy initialization, the components properties are not filled by the proxy. To be sure that this is a bug I tried the following:
Code:
session.Get(typeof(Category), 2); // assuming that product.Category.Id = 2
if (product.Category.Depth == 1) { ... }
, which works OK, as the instance has already been filled by .Get. As you can imagine setting the product-category relation as [lazy="false" fetch="join"] solves this issue, but I think it should be consider a bug.