HQL加入查询以急切获取大量关系
我的项目最近发现Hibernate可以采用多级关系,并且在单个连接HQL中急切地获取它们以生成我们需要的填充对象。 我们喜欢这个function,认为它会胜过懒惰的获取环境。
问题是,我们遇到的情况是,单个父母有十几个直接关系,一些子关系,其中一些在几个实例中有几十行。 结果是一个非常大的交叉产品,导致hql几乎永远地旋转它的轮子。 在我们放弃并杀死它之前,我们将记录变为11并且看到了超过100000次迭代。
很明显,虽然这种技术在某些情况下很有用,但它具有生活中的一切限制。 但是hibernate中最好的替代方案是什么呢? 我们不想懒惰加载这些,因为我们将进入更加糟糕的N + 1情况。
理想情况下,我希望让Hibernate预取所有的行和细节,但一次只做一个关系,然后将正确的细节对象保湿到正确的父对象,但我不知道它是否做了这样的事情。
建议?
更新:
所以我们得到了SQL这个查询生成的,事实certificate我错误地诊断了这个问题。 交叉产品并不是那么大。 我们直接在数据库中运行相同的查询,并在一秒钟内返回500行。
然而我们在hibernate日志中非常清楚地看到它进行了100K迭代。 是否有可能Hibernate会陷入你的人际关系或某事的循环中?
或者这应该被问为一个新问题?
我们的团队使用特殊策略与协会合作。 collections是懒惰的,单一关系也是懒惰的,除了简单结构的引用(例如国家参考)。 我们使用fluent-hibernate在具体情况下加载我们需要的东西。 这只是因为流利的hibernate支持嵌套的投影。 您可以参考此unit testing以查看如何部分加载复杂对象网络。 unit testing的代码片段
List roots = H. 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转换平面结果集
- 错误:无法创建PoolableConnectionFactory(isValid()返回false)
- 如何使用Hibernate注释将Java日期映射到mysql中的DATETIME(默认情况下为TIMESTAMP)
- Hibernate命名查询及其性能优势?
- 带有Hibernate的org.hibernate.hql.ast.QuerySyntaxException
- 使用JPA在PostgreSQL中保留UUID
- Jersey,Guice和Hibernate – EntityManager线程安全
- Spring hibernate模板列表作为参数
- 复制一组实体并在Hibernate / JPA中保留
- 为什么在Spring 3.1和hibernate 4中找到当前线程exception的No Session