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

发布于 2024-07-25 13:43:25 字数 1958 浏览 7 评论 0原文

我遇到了一些极其奇怪的行为,NHibernate 查询开始挂起。 我制作了一个演示项目,以可重复的方式展示这种行为。

您可以在此处下载该项目,

这是有问题的代码:

    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 的查询已发送到服务器,但它停在那里:

第一个请求(行为符合预期):

良好请求 http://muc-central.com/misc/good_request.jpg

第二个请求(挂起):

替代文本 http://muc-central.com/misc/hanging_request.jpg

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪#恶を代价 2024-08-01 13:43:25

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

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.

蘸点软妹酱 2024-08-01 13:43:25

我通过切换到 LinFu proxyfactory.factory_class 修复了挂起问题。 不知道为什么这有效,而 Castle 却不行。 将了解有关动态代理的更多信息并找出我应该提交哪种错误报告。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文