HQL 加入查询以急切获取大量关系 [英] HQL joined query to eager fetch a large number of relationships

查看:26
本文介绍了HQL 加入查询以急切获取大量关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目最近发现 Hibernate 可以采用多个级别的关系,并在单个连接 HQL 中急切地获取它们以生成我们需要的填充对象.我们喜欢这个功能,认为它会胜过懒惰的获取情况.

My project has recently discovered that Hibernate can take multiple levels of relationship and eager fetch them in a single join HQL to produce the filled object we need. We love this feature, figuring it would outperform a lazy fetch circumstance.

问题是,我们遇到了这样一种情况:单亲父母有大约十几个直接关系,还有几个子关系,其中一些在少数情况下有几十行.结果是一个相当大的交叉产品,导致 hql 几乎永远旋转它的轮子.在我们放弃并杀死它之前,我们将日志记录设置为 11,并看到了超过 100000 次迭代.

Problem is, we hit a situation where a single parent has about a dozen direct relationships, an a few subrelationships off of that, and a few of them have several dozen rows in a few instances. The result is a pretty large cross-product that results in the hql spinning it's wheels virtually forever. We turned logging up to 11 and saw more than 100000 iterations before we gave up and killed it.

很明显,虽然这种技术在某些情况下非常有用,但它与生活中的一切一样都有局限性.但是在休眠状态下,性能最佳的替代方案是什么?我们不想延迟加载这些,因为我们会进入更糟糕的 N+1 情况.

So clearly, while this technique is great for some situations, it has limits like everything in life. But what is the best performing alternative in hibernate for this? We don't want to lazy-load these, because we'll get into an N+1 situation that will be even worse.

理想情况下,我希望 Hibernate 预取所有行和详细信息,但一次只执行一个关系,然后将正确的详细信息对象添加到正确的父项中,但我不知道它是否会这样做一个东西.

I'd ideally like to have Hibernate pre-fetch all the rows and details, but do it one relationship at a time, and then hydrate the right detail object to the right parent, but I have no idea if it does such a thing.

建议?

更新:

所以我们得到了这个查询生成的SQL,结果是我误诊了问题.交叉产品不是那么大.我们直接在我们的数据库中运行了相同的查询,并在短短一秒钟内返回了 500 行.

So we got the SQL this query generated, it turns out that I misdiagnosed the problem. The cross product is NOT that huge. We ran the same query in our database directly and got 500 rows returned in just over a second.

然而,我们在休眠记录中非常清楚地看到它进行了 10 万次迭代.Hibernate 是否有可能陷入你的人际关系或其他事情的循环中?

Yet we saw very clearly in the hibernate logging it making 100K iterations. Is it possible Hibernate can get caught in a loop in your relationships or something?

或者这应该作为一个新问题提出?

Or maybe this should be asked as a new question?

推荐答案

我们的团队使用特殊策略与协会合作.集合是惰性的,单一关系也是惰性的,除了结构简单的引用(例如国家引用).我们使用 fluent-hibernate 来加载我们在具体情况下需要的内容.这仅仅是因为 fluent-hibernate 支持嵌套投影.你可以参考这个 单元测试 以了解如何部分加载复杂的对象网络.来自单元测试的代码片段

Our team uses the special strategy to work with associations. Collections are lazy, single relations are lazy too, except references with simply structure (for an example a countries reference). And we use fluent-hibernate to load what we need in a concrete situation. It is simply because of fluent-hibernate supports nested projections. You can refer this unit test to see how complex object net can be partially loaded. A code snippet from the unit test

 List<Root> roots = H.<Root> request(Root.class).proj(Root.ROOT_NAME)
            .innerJoin("stationarFrom.stationar", "stationar")
            .proj("stationar.name", "stationarFrom.stationar.name")
            .eq(Root.ROOT_NAME, rootName).transform(Root.class).list();

另见

如何使用 Hibernate 转换平面结果集

这篇关于HQL 加入查询以急切获取大量关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆