当实体上存在惰性属性时,NHibernate的criteria.List()会挂起

时间:2009-06-24 16:52:51

标签: nhibernate lazy-loading session-management

我已经得到了一些非常奇怪的行为,其中NHibernate查询开始挂起。我做了一个演示项目,以可重复的方式展示了这种行为。

您可以下载项目here

以下是有问题的代码:

    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;
        }
    }

关键行是作者字段上的.SetFetchMode。在我的演示项目的第一次加载它加载正常。当我点击刷新时,它会挂起并且永远不会超过crit.List()调用。随着加载的热情,它每次都有效。

我正在使用Castle.Facilities.NHibernateIntegration.Components.SessionWebModule来确保每个请求有1个会话。

我发现的另一个奇怪的事情是,这只发生在SQL Server上。当我使用SQLite时,一切正常。在我的演示项目中,我有一个简单的构建标志,允许您轻松切换数据库。只需查看/ build目录中的local.properties.xml。

我知道在这种特殊情况下,急切加载解决了我的问题,但在我的应用程序中,我不想急于加载所有内容。

请下载解决方案并亲自尝试。我已经在其他机器上尝试过,他们做同样的事情。

以下是一些SQL Profiler捕获。您可以看到Posts的查询已发送到服务器,但它停在那里:

第一个请求(按预期行事):

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

第二个请求(挂起):

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

2 个答案:

答案 0 :(得分:0)

好吧,我认为这是在Windows服务器上运行所以我不知道相当于htop但是我打赌你在数据库/会话代码的某个地方有一个死锁你应该能够检查线程状态以查看是否每个线程都处于等待状态。

答案 1 :(得分:0)

我通过切换到LinFu proxyfactory.factory_class来修复挂起。不知道为什么这个有用,而Castle也没有。要了解有关动态代理的更多信息,并找出我应提交的错误报告类型。