HQL将查询连接到渴望获取大量的关系



我的项目最近发现Hibernate可以接受多个级别的关系,并在单个连接HQL中快速获取它们,以生成我们需要的填充对象。我们喜欢这个特性,认为它的性能会优于lazy fetch环境。

问题是,我们遇到了这样一种情况,单亲双亲有大约12个直接关系,以及一些子关系,其中一些在几个实例中有几十行。结果是一个相当大的交叉积,导致hql几乎永远旋转它的轮子。在我们放弃并终止它之前,我们将日志记录增加到11次,并且看到了超过100000次的迭代。

所以很明显,虽然这种技术在某些情况下很好,但它有局限性,就像生活中的一切一样。但是在hibernate中性能最好的替代方案是什么呢?我们不想惰性加载这些,因为我们会遇到N+1的情况,这会更糟。

理想情况下,我想让Hibernate预取所有的行和细节,但一次做一个关系,然后将正确的细节对象添加到正确的父对象,但我不知道它是否做这样的事情。

建议吗?

更新:

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

然而,我们在hibernate日志中非常清楚地看到它进行了100K次迭代。是否有可能Hibernate会在你的关系中陷入循环或其他什么?

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

我们的团队使用特殊的策略来处理关联。集合是惰性的,单个关系也是惰性的,除了结构简单的引用(例如国家引用)。我们使用fluent-hibernate来加载我们在具体情况下需要的东西。这仅仅是因为fluent-hibernate支持嵌套投影。您可以参考这个单元测试来了解如何部分加载复杂的对象网。单元测试

中的代码片段
 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转换平面结果集

最新更新