那些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;
}
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
但是,如果我正在做:
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
答案 0 :(得分:1)
在此链接上有一些关于批量获取mkyong的信息。
要解决此问题,您可以使用fetch。
我认为理解差异的关键在于查看每次加载数据的方式。根据标准,一组大师加载,但有 em.find(class,id),每次只检索一个。我不完全确定这是否是原因,但也许有人可以带来更多的光。
答案 1 :(得分:0)
我发现了问题。我将CDI与绑定到请求范围的实体管理器一起使用。问题是方法getMastersFromJPACriteria在ejb上声明,我的实体管理器在事务的提交时刷新。即使我的主实体在方法调用后仍处于MANAGED状态,似乎在会话刷新时清除了Batch Collection Queue from Hibernate!这在issue中进行了解释。