【问题标题】:NHibernate's criteria.List() hangs when lazy property exists on entity当实体上存在惰性属性时,NHibernate 的 criteria.List() 挂起
【发布时间】:2009-06-24 16:52:51
【问题描述】:

我遇到了一些非常奇怪的行为,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

【问题讨论】:

  • 您处理它多久了?你确定它真的挂了,而不是很长一段时间都很忙吗?您是否查看过使用 NH Profiler 来查看 NH 在您第二次调用 List 时做了什么?
  • 我去吃午饭的时候就让它继续,但它仍然没有完成。我用 NHProf 对其进行了测试,我可以看到查询命中了数据库服务器。我也可以通过 SQL Server Profiler 来判断。

标签: nhibernate lazy-loading session-management


【解决方案1】:

好吧,我假设这是在 Windows 服务器上运行的,所以我不知道与 htop 等效,但我敢打赌,数据库/会话代码中的某处存在死锁,你应该能够检查线程状态以查看是否每个线程都处于等待状态。

【讨论】:

  • 欢迎使用 StackOverflow rdickie ;-) 刚刚发现它与 SQLite 配合得很好。开始认为这是一个数据库连接问题,但仍需要进一步缩小范围。
【解决方案2】:

我通过切换到 LinFu proxyfactory.factory_class 解决了这个问题。不知道为什么这行得通,而城堡却不行。将进一步了解动态代理并确定我应该提交什么样的错误报告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    相关资源
    最近更新 更多