1

I have the following query:

ObjectB objectBAlias = null;
ObjectC objectCAlias = null;
var query = session.QueryOver<ObjectA>();
var results = query
    .JoinAlias(x => x.listOfBs, () => objectBAlias)
    .JoinAlias(x => objectBAlias.ObjectC, () => objectCAlias)
    .TransformUsing(new DistinctRootEntityResultTransformer())
    .List<ObjectA>();

class ObjectA
{
    IList<ObjectB> listOfBs;
}

class ObjectB
{
    ObjectA a;
    ObjectC c;
}

class ObjectC
{
    int x;        
}

ObjectA has a many-to-many relationship to ObjectC with ObjectB being the joining table. ObjectA has a list of ObjectB's, and ObjectB has a proporty of ObjectC. I'm trying to eager load ObjectC but have had no success.

The only way I've gotten all the ObjectCs to eager load was by doing this:

foreach (ObjectA a in results)
{
    foreach (var b in a.listOfBs)
    {
        NHibernateUtil.Initialize(b.c);
    }
}

But this doesn't seem like something that would scale very well.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
dmarsi
  • 194
  • 1
  • 10

1 Answers1

1

I would suggest - do not try that (eager loading of many-to-many). Instead - use built in feature:

19.1.5. Using batch fetching

NHibernate can make efficient use of batch fetching, that is, NHibernate can load several uninitialized proxies if one proxy is accessed (or collections. Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level.

To get more details check these:

Fetching Collections is a difficult operation. It has many side effects (as you realized, when there are fetched more collections). But even with fetching one collection, we are loading many duplicated rows.

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • So would putting a `batch-size` on ObjectB allow me to then call `result[0].listOfBs[0].c.x` outside of the session (aka eager loaded)? Or am I looking at this the wrong way? – dmarsi Sep 22 '15 at 16:23
  • That setting I place on both sides! 1) on ` – Radim Köhler Sep 22 '15 at 16:24
  • That looks like it did the trick, thanks! Any chance you could explain what it's doing? – dmarsi Sep 22 '15 at 16:29
  • 1
    Yes! The point here is that we use some **"optimisation" setting**. It is intended to solve the 1 + N issue. It creates some more smart selects *(with a pretty large `IN` statement)* to load as **many** entities in as a **few** DB roundtrips as possible. We than easily query over the root entity, and get all touched relations - 1) lazily and 2) in batches *(see another details here http://stackoverflow.com/a/32456516/1679310)..* hope it helps a bit. Enjoy mighty NHibernate, sir ;) – Radim Köhler Sep 22 '15 at 16:33