views:

425

answers:

2

Using Castle ActiveRecord, I stumbled into a problem when lazy-loading.

The following works (obviously)

using (new SessionScope())
{
    User singleUser = User.FindFirst(...)
    UserGroup groups = singleUser.Groups; // Lazy-loading groups.
}

Since I need to modify the session filters in a certain context (using interceptors), I create a new SessionScope.

using (new SessionScope())
{
    User singleUser;
    EnableVariousFiltersInThisThread();
    using (new SessionScope())
    {
        singleUser = User.FindFirst(...);
    }
    DisableVariousFiltersInThisThread();
    UserGroup groups = singleUser.Groups; // Lazy-loading groups.
}

The last line "singleUser.Groups" throws a LazyInitializationException: "failed to lazily initialize a collection of role: Groups, no session or session was closed".

However, all other session operations work correctly. So it seems that "singleUser" is bound to the now disposed SessionScope. Why? And how can this be solved alternatively?

+3  A: 

I believe this is the way NHibernate works.

Your entities are all associated with a session and use this for lazy loading. If you dispose your session, you can't fetch lazy loaded collections and properties. The answer, obvious considering this limitation, is to avoid disposing the session - or to keep the session alive until you have extracted the data you need.

The inner scope is no different from the outer; it doesn't support lazy loading outside this scope either.

You can however work around this limitation, if you trick NHibernate into eager loading within your inner scope. Alternatively, call .ToList() or similar on the collections you would want to work with, before existing the scope and the data will also be available outside.

troethom
Obviously it is how NHibernate works. The question is why :-) Thanks for the alternative suggestions.
mbp
A: 

My GUESS is - part of the reason is about "Identity Map". Not only lazy loaded objects, but also all objects are bound to a session. This makes sure no two objects represent a single row in database.

Canton