2

I would like to override the default lazy loading behavior which is set in mappings as 'lazy=false'. Can't change it as many parts of existing application depend on this setting.

After spent some hours on it I didn't find a solution so I'm asking here. How to do this?
What I want to achieve is to fine tune my query to load only what is needed.
This is what I've tried already:

Using QueryOver api:

var properties = session.QueryOver<Property>()
    .Fetch(prop => prop.Transactions).Eager
    .Fetch(prop => prop.Districts).Eager
    //I dont want to load those entities below so I mark
    //them as lazy - IT DOESN'T WORK
    //I can see in SQL that they are getting loaded in separate queries
    .Fetch(prop => prop.Districts.First().Aliases).Lazy
    .Fetch(prop => prop.Districts.First().PolygonPoints).Lazy
    .Skip(i * pageSize)
    .Take(pageSize)
    .List();

Using Criteria api:

var criteria = session.CreateCriteria<Property>();
    criteria.SetFetchMode("Transactions", NHibernate.FetchMode.Join);
    criteria.SetFetchMode("Districts", NHibernate.FetchMode.Join);
    criteria.SetFetchMode("Districts.Aliases", NHibernate.FetchMode.Select); // tried Lazy too
    criteria.SetFetchMode("Districts.PolygonPoints", NHibernate.FetchMode.Select); // tried Lazy too
    criteria.AddOrder(NHibernate.Criterion.Order.Asc("Id"));
    criteria.SetFirstResult(i * pageSize);
    criteria.SetMaxResults(pageSize);
    var properties = criteria.List<Property>();

Using any of the above methods 'Aliases' and 'PolygonPoints' are always being loaded when calling List<>(). I don't need them in my process.

I'm using Nhibernate 4.0.
Any ideas?

3
  • You could try making all the properties virtual. Ah... and how did you define Districts.Aliases? What collection is it using? Commented May 11, 2015 at 11:55
  • All the properties are required to be virtual (and they are) when using Nhibernate. The collection type is ICollection<> Commented May 11, 2015 at 12:18
  • If I recall correctly with HQL Lazy setting is disregarded. Perhaps you can use an HQL query Commented May 11, 2015 at 17:15

1 Answer 1

2

We cannot override mapping in this case. We can do it opposite way - have lazy in place - and use eager fetching for querying.

The decision process (of reference loading) is done outside of the query, ex post. So it could be pre-loaded, but cannot be avoided.

Solution here could be of two types.

  • The first is preferred (by me) - do your best and make laziness the default: Ayende - NHibernate is lazy, just live with it
  • Use projections. Instruct NHibernate to create just one query, use transformer to get expected object graph - without any proxies in it

There is pretty clear example how to (properly) use projection list even for references:

And we would also need Custom result transformer, which will ex-post create all the references from the returned data:

Sign up to request clarification or add additional context in comments.

2 Comments

Too bad. I'm going to trust you on this I guess =]
I really do wish to have answer like "turn this on... all done". But... Anyhow, I still would say, that we can make it - even with projections. ;) Enjoy NHibernate, sir! It is awesome tool ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.