Search code examples
nhibernatelazy-loadingsession-management

NHibernate's criteria.List() hangs when lazy property exists on entity


I've been getting some extremely bizarre behaviour where NHibernate queries start to hang. I've made a demo project that exhibits this behaviour in a repeatable fashion.

You can download the project here

Here's the offending code:

    public IList<Post> GetLatestLiveBlogEntries(int numEntriesToRetrieve)
    {
        var maxDate = DateTime.Now;

        using (var session = SessionManager.OpenSession())
        {
            var crit = session.CreateCriteria(typeof (Post))
                .Add(Restrictions.Eq("Enabled", true))
                .Add(Restrictions.Lt("postDate", maxDate))
                .AddOrder(new Order("postDate", false))
                //.SetFetchMode("author", FetchMode.Eager) // <-- the exclusion of this line breaks everything!
                .SetMaxResults(numEntriesToRetrieve);

            StupidFileLogger.Log("If this is the last log, I'm hanging on crit.List<Post>()");
            var listOfPosts = crit.List<Post>();
            StupidFileLogger.Log("I actually was able to retrieve the posts");
            return listOfPosts;
        }
    }

The key line is the .SetFetchMode on the author field. On the first load of my demo project it loads fine. When I hit refresh, it hangs and never gets past the crit.List() call. With eager loading it works everytime.

I'm using Castle.Facilities.NHibernateIntegration.Components.SessionWebModule to ensure 1 session per request.

The other bizarre thing I've found is that this only happens with SQL Server. When I use SQLite everything works fine. In my demo project I have a simple build flag that allows you to switch db's easily. Just look at local.properties.xml in the /build directory.

I understand that eager loading solves my issue in this particular case, but in my application I don't want to have to eager load everything.

Please download the solution and try for yourself. I've tried it on other machines and they do the same thing.

Here are some SQL Profiler captures. You can see that the query for Posts was sent to the server, but it stops there:

First request (behaves as expected):

good request http://muc-central.com/misc/good_request.jpg

Second request (hangs):

alt text http://muc-central.com/misc/hanging_request.jpg


Solution

  • I fixed the hang by switching to the LinFu proxyfactory.factory_class. Have no idea why this works and Castle doesn't. Going to learn more about Dynamic Proxies and figure out what kind of bug report I should submit.