views:

127

answers:

1

I have a tree where every node is a Resource class:

public abstract class Resource 
{ 
        public virtual Guid Id { get; set; } 
        public virtual Resource Parent { get; set; } 
        public virtual IList<Resource> ChildResources { get; set; } 
}

as you can see this class is abstract and there are many different derived classes from Resource (3 at the moment, more to come).

In my database i have a table for Resource, and a table for each class which derives from Resource. These are mapped together with <joined-subclass>.

I've read this:

http://ayende.com/Blog/archive/2009/08/28/nhibernate-tips-amp-tricks-efficiently-selecting-a-tree.aspx

and i have the same code as Ayende to load my tree:

var resource = UnitOfWork.Current.Session
    .CreateQuery("from Resource r join fetch r.ChildResources")
    .SetResultTransformer(new DistinctRootEntityResultTransformer())
    .SetReadOnly(true)
    .List<Resource>();

which is all working fine (all Resources are returned with a single select) However, I'm seeing extra selects occurring as I enumerate a Resource's ChildResources list.

Is that because of this?:

http://ayende.com/Blog/archive/2009/09/03/answer-the-lazy-loaded-inheritance-many-to-one-association-orm.aspx

Either way, how do I prevent this from happening?

Here's the part of the mappings for the relationships (class names trimmed for clarity):

<bag cascade="save-update" fetch="join" lazy="false" inverse="true" name="ChildResources"> 
        <key> 
                <column name="Parent_Id" /> 
        </key> 
        <one-to-many class="Resource" /> 
</bag> 
<many-to-one class="Resource" name="Parent"> 
        <column name="Parent_Id" /> 
</many-to-one>

Thanks

UPDATE

Slight oversight, its only issuing extra selects when enumerating the child collections of the leaf nodes in the tree...

A: 

Either do this:

<bag ... lazy="false">

to eager fetch the items always, or do this (in HQL):

var resources = session.CreateQuery("from Resource r join fetch r.ChildResources");
mookid8000
The lazy=false makes no difference, and that is the HQL im using. When that HQL is executed i get all Resource rows returned from the db, great :) but... when i enumerate ChildResources, it hits the db again doing "select from Resource where Parent_id = `<someid>`
Andrew Bullock
I've updated the question to reflect this, and also something else ive discovered
Andrew Bullock