R – NHibernate’s criteria.List() hangs when lazy property exists on entity

lazy-loadingnhibernatesession-management

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

Best Answer

Well, I assume this is running on a windows server so I dont know the equivalent to htop but I bet you there is a deadlock somewhere in the database/session code and you should be able to check the thread state to see if every thread is in the waiting state.

Related Topic