2012-07-14 52 views
1

我们将Hibernate 4.1.4与实体管理器实现结合使用,对此非常满意。当加载一个实体或一小组实体(10-50个子实体)时,我们会获得出色的性能,而且我们所有的联接都很好,而且是双向的。编辑/保存/删除是一件轻而易举的事!在实体管理器中使用Hibernate 4.1和JPA 2.0,将子实体下载到多个级别的多个实体的最佳方式是什么?

加载2500个实体&相关报表数据

我们遇到了问题,当我们试图加载实体的数百或数千使用子实体一起。在一个例子中,我们有大约2500个基本实体以及两个一对一和三个一对多连接。这导致2500 x 5 +1查询。花费大约30秒来执行我们的数据库(DB2)。

我们使用动态查询和实体管理器创建查询方法:

http://docs.jboss.org/hibernate/orm/4.1/javadocs/

http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html

试图哄休眠到使用加入

我们的观察一直没有无论我们尝试什么,我们似乎都无法让hibernate在主查询上执行加载的子实体作为连接。当使用find方法和主键hibernate使用连接加载单个实体时,但是当加载多个基础实体时,它不会。

我们尝试过使用相同结果的标准api。

一些成功的查询检索多个实体

例子:

select a,b from table1 a left join table2 b 

我们有部分成功做在我们的查询手动连接,并通过元组检索各个实体,但这种绕过我们的注解实体模型,并不是首选的方法(如果我们可以避免它)。

http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#objectstate-querying-executing

我们与元组遇到的问题是,他们是从主要实体(这似乎是合乎逻辑的,因为他们没有通过注解关系加载),而且似乎没有办法重新连接它们分离。在手动添加实体列表中的所有一对多记录后,当hibernate达到列表的get方法时,它仍会尝试急切/懒惰地加载列表(尽管列表已被设置)。

试图优化 - 数据的预压设置

另外,我们试图优化技术是预加载提前数据集。加载所有核心实体后,我们构建了pk的列表,并激发了单个查询以加载所有一对多数据集。但是,当hibernate再次访问列表数据的getter时,它又会尝试急于/懒加载列表,而忽略会话中已经预先加载的内容(可能需要启用缓存?)。

对此有何建议?

我们正朝许多不同的方向发展,并且收效甚微,并希望有人能够指引我们走向正确的道路(或指出一条新道路!)!

回答

1

似乎我已经想通了自己!两个策略解决了这个问题:

  1. 在查询中加入提取需要照顾一对多连接!当然你只能做一次连接抓取,因为Hibernate会抛出不能同时抓取多个包的异常。

    例子:

    LEFT OUTER JOIN FETCH t.table3 t3 
    
  2. 有关更多加入@Fetch(FetchMode.SUBSELECT)的伎俩!

有效地将总查询从数千个减少到少数。在一个例子中,选择了188个核心实体并且共执行了12个查询。额外的查询大多是一对一的查询,并且对总执行时间没有显着影响(平均1-2秒)。无论是选择188或1888记录,查询总数都不会显着增加。

如果有人想了解更多信息,请随时与我联系或发表评论! :)

相关问题