Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate: How to perform eager subselect fetching of many children & grandchildren (object graph) in a single round-trip to the database?

First, please don't try to argue me out of doing the eager load - traversing the object graph and causing (by lazy loading) even more than ONE round-trip to the database is just not an option.

I have a big object graph. I want to fetch the root object, plus a subset of its children, grandchildren, great-grandchildren, etc. Currently I do this by creating multiple Future objects (with Criteria) and in each one, I do SetFetchMode("...", FetchMode.Eager) - see Ayende's post and Sam's 3rd comment here. There are two problems:

  1. NHibernate performs multiple select queries in the same round-trip - one for each path from root to a leaf (A.B.C.D), which is great, but uses join rather than subselect which is what I really want it to do. Using join means a ton of data needs to be sent from the database, needs to be parsed, and nhibernate needs to do a lot more work than necessary.

  2. As a result of problem 1 - duplication of objects nested more than one level deep in some cases.

The second problem I "solved" by setting my collections to be Set, but then I lose the ordering ability - since I must specify ISet as the interface, there's no way for my code to know if the set is really an OrderedSet.

Does anyone know how to perform, in a single round-trip, eager loading of an object plus several deeply nested collections, but not using join?

I'd be extremely grateful! I've scoured the web for answers, apparently I'm not the first to hit this wall.

like image 987
sinelaw Avatar asked Mar 10 '11 15:03

sinelaw


1 Answers

You can create a separate queries with only 1 call to SetFetchMode and run them in one go using MultiCriteria (or Futures or whatever you want to use). After that, only the result from the first query is relevant to you. This will give you a single result in an single round-trip.

like image 128
Pieter Avatar answered Nov 16 '22 02:11

Pieter