2010-11-09 28 views
1

我正在使用hibernate的批量提取来提高查询性能。在我的persistence.xml我已经添加了以下设置:休眠:批量提取的意外获取顺序

<property name="hibernate.default_batch_fetch_size" value="50"/> 

我有一个实体A,其中有一个1:N关系的实体B.此关系的数据是获取懒洋洋地。现在,我已经得到了以下情况:

  • 我负载类型中的10000个实体从DB
  • 我遍历这些实体,并通过调用初始化a.getBs懒惰的关系()大小()
  • 这样做时,hibernate不仅会初始化当前实体的依赖关系,还会从列表中加载49个附加实体的依赖关系。这种行为是预期的。

生成的SQL类似于这样:

select 
    b0_.SOMETHING as SOMETHING1_1_, 
    ... 
from 
    XYZ.B b0_ 
where 
    b0_.A_ID in (
     ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ... 
    ) 

我真正的问题是,Hibernate是不加载结果列表中的实体按预期的顺序。当我从列表中访问第一个条目时,它不会加载实体2-50的数据,但会从列表中加载49个随机条目的数据。 (例如,它可以初始化实体3,7,100,2001 ...的数据)。这种行为很奇怪,我想知道如何改变它以预期的顺序加载数据。

当前存在的问题,与所描述的行为有关。

  • 内存使用情况。在迭代列表时,hibernate正在初始化大量数据,这将在稍后需要。除了上面的算法外,我还添加了一些代码,它从列表中删除处理过的记录并调用session.evict(entity),使实体符合垃圾回收的条件。这当然不是现在。
  • 迭代开始时,查询速度非常慢,因为hibernate正在查询几乎每个处理实体的数据库。这会导致问题,因为我正在将实体写入Web应用程序的流中,以便在处理时进行下载。结果,下载速度在开始时非常缓慢,并且在更多实体加载到内存并且需要更少的数据库调用时加速。

非常感谢您的帮助和问候

托马斯

+0

你在使用列表iterator()吗? – KarlP 2010-11-09 16:57:44

+0

我测试了迭代器和新的for循环(for(A a:resultlist)) – Thomas 2010-11-10 12:48:39

回答

2

当你说的Hibernate没有按预期的顺序加载实体,你告诉它预期的顺序是什么?也就是说,B的映射是否包含order-by属性?如果没有,那么他们 Hibernate数据模型中没有顺序,并可以以任何顺序(可能是数据库默认值)加载。

否则,我的理解是,Hibernate应该在查找要加载的pkeys时应用顺序约束。因此,可能值得在邮件列表中将它作为潜在的错误。