Hi,
I'm still a relative newcomer to NHibernate, but I've been puzzling with this issue for a while and haven't come up with a reasonable answer.
I'm using NH 2.0.1 GA with SQL 2005 db.
Basically the issue is that in certain circumstances, NHibernate is ignoring the fetch strategy on a one-to-many collection that I have specified as "join" and instead using a single select.
To illustrate this I knocked up a simple example (excuse the dodgy object model!)...
My mapping looks like this...
Code:
<class name="Parent">
<id name="ParentID">
<generator class="identity" />
</id>
<property name="FirstName" />
<property name="LastName" />
<bag name="Children">
<key column="ParentID"/>
<one-to-many class="Child"/>
</bag>
</class>
<class name="Child">
<id name="ChildID">
<generator class="identity" />
</id>
<property name="FirstName" />
<property name="LastName" />
<bag name="Grandchildren" fetch="join">
<key column="ChildID"/>
<one-to-many class="Grandchild"/>
</bag>
<many-to-one name="Parent" class="Parent" column="ParentID"/>
</class>
<class name="Grandchild">
<id name="GrandchildID">
<generator class="identity" />
</id>
<property name="FirstName" />
<property name="LastName" />
<many-to-one name="Parent" class="Child" column="ChildID"/>
</class>
---------------------------
So my two scenarios are this...
1)
Code:
using (ISession session = NHibernateHelper.OpenSession())
{
Child child = session.Get<Child>(1);
Grandchild gc = child.Grandchildren[0];
}
This executes fine and leads to a single SQL statement as expected -
Code:
NHibernate: SELECT child0_.ChildID as ChildID1_1_, child0_.FirstName as FirstName1_1_, child0_.LastName as LastName1_1_, child0_.ParentID as ParentID1_1_, grandchild1_.ChildID as ChildID3_, grandchild1_.GrandchildID as Grandchi1_3_, grandchild1_.GrandchildID as Grandchi1_2_0_, grandchild1_.FirstName as FirstName2_0_, grandchild1_.LastName as LastName2_0_, grandchild1_.ChildID as ChildID2_0_ FROM Child child0_ left outer join Grandchild grandchild1_ on child0_.ChildID=grandchild1_.ChildID WHERE child0_.ChildID=@p0; @p0 = '1'
2)
Code:
using (ISession session = NHibernateHelper.OpenSession())
{
IList<Parent> parents = session.CreateCriteria(typeof(Parent)).List<Parent>();
Child child = parents[0].Children[0];
Grandchild gc = child.Grandchildren[0];
}
This executes 3 selects (rather than the 2 I would expect)
Code:
NHibernate: SELECT this_.ParentID as ParentID0_0_, this_.FirstName as FirstName0_0_, this_.LastName as LastName0_0_ FROM Parent this_
NHibernate: SELECT children0_.ParentID as ParentID1_, children0_.ChildID as ChildID1_, children0_.ChildID as ChildID1_0_, children0_.FirstName as FirstName1_0_, children0_.LastName as LastName1_0_, children0_.ParentID as ParentID1_0_ FROM Child children0_ WHERE children0_.ParentID=@p0; @p0 = '1'
NHibernate: SELECT grandchild0_.ChildID as ChildID1_, grandchild0_.GrandchildID as Grandchi1_1_, grandchild0_.GrandchildID as Grandchi1_2_0_, grandchild0_.FirstName as FirstName2_0_, grandchild0_.LastName as LastName2_0_, grandchild0_.ChildID as ChildID2_0_ FROM Grandchild grandchild0_ WHERE grandchild0_.ChildID=@p0; @p0 = '1'
Can anyone explain why in the second example, it is still performing an extra select to get the Grandchildren rather than joining as it did in the first example? Maybe I'm doing something stupid, but it's got me stumped!
Thanks in advance