Hibernate @BatchSize和JPA Criteria API

时间:2016-03-21 17:13:21

标签: java hibernate jpa wildfly

那些2之间是否存在不兼容性?

我有一个n + 1问题,我尝试使用专有的hibernate @BatchSize注释来解决。

public class Master{

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "master", orphanRemoval = true, cascade = CascadeType.ALL)
    @BatchSize(size=100)//how many item collections we want to load from <b>other<b> Masters currently in the PC
    private Set<Detail> details;

}

public class Detail{
  private Master master;
}

案例1

List<Master> masters = getMastersFromJPACriteria(complexParams);
assert(masters.size() == 3);
masters.get(0).getDetails().size();

它应该触发详细信息的批量收集:

SELECT * FROM DETAIL WHERE MASTER_ID IN (1,2,3)

但我有(N + 1期):

SELECT * FROM DETAIL WHERE MASTER_ID = 1

案例2

但是,如果我正在做:

m1 = entityManager.find(Master.class,1L);
entityManager.find(Master.class,2L);
entityManager.find(Master.class,3L);

m1.getDetails().size();

它正确触发:

SELECT * FROM DETAIL WHERE MASTER_ID IN (1,2,3)

我不明白为什么在案例1中细节集合不是批量加载的。

环境:Wildfly 8.2.0.Final with Hibernate 4.3.7

2 个答案:

答案 0 :(得分:1)

在此链接上有一些关于批量获取mkyong的信息。

要解决此问题,您可以使用fetch

我认为理解差异的关键在于查看每次加载数据的方式。根据标准,一组大师加载,但有 em.find(class,id),每次只检索一个。我不完全确定这是否是原因,但也许有人可以带来更多的光。

答案 1 :(得分:0)

我发现了问题。我将CDI与绑定到请求范围的实体管理器一起使用。问题是方法getMastersFromJPACriteria在ejb上声明,我的实体管理器在事务的提交时刷新。即使我的主实体在方法调用后仍处于MANAGED状态,似乎在会话刷新时清除了Batch Collection Queue from Hibernate!这在issue中进行了解释。