【发布时间】:2016-01-18 09:32:11
【问题描述】:
我的项目最近发现 Hibernate 可以采用多个级别的关系,并在单个连接 HQL 中急切地获取它们以生成我们需要的填充对象。我们喜欢这个功能,认为它会胜过惰性获取情况。
问题是,我们遇到了这样一种情况,即单亲父母有大约十几个直接关系,还有几个子关系,其中一些在少数情况下有几十行。结果是一个相当大的交叉产品,导致 hql 几乎永远旋转它的轮子。在我们放弃并杀死它之前,我们将日志记录提高到 11 次,并且看到了超过 100000 次迭代。
很明显,虽然这项技术在某些情况下非常有用,但它也有限制,就像生活中的一切一样。但是,在hibernate中表现最好的替代品是什么?我们不想延迟加载这些,因为我们会陷入 N+1 的情况,情况会更糟。
理想情况下,我希望 Hibernate 预取所有行和细节,但一次只做一个关系,然后将正确的细节对象水合到正确的父级,但我不知道它是否这样做一个东西。
建议?
更新:
所以我们得到了这个查询生成的SQL,结果是我误诊了问题。交叉产品不是那么大。我们直接在我们的数据库中运行相同的查询,并在一秒钟内返回了 500 行。
然而,我们在休眠日志中非常清楚地看到它进行了 10 万次迭代。 Hibernate 是否有可能陷入您的人际关系或其他什么的循环中?
或者也许这应该作为一个新问题提出?
【问题讨论】:
-
看看JPA Entity Graphs。有了这些,您可以向 JPA 提供者提示您希望急切加载的内容。一个 smart(TM) 提供者将找到一种减少 SELECT 数量的好方法,而不必交叉连接所有实体。 (Hibernate 在这种优化上的表现似乎比 EclipseLink 更好。)
标签: java database performance hibernate jpa