【问题标题】:Hibernate @BatchSize and JPA Criteria APIHibernate @BatchSize 和 JPA Criteria API
【发布时间】:2016-03-21 17:13:21
【问题描述】:

这两者之间有不兼容的地方吗?

我有一个n + 1 问题,我尝试使用专有的休眠@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 和 Hibernate 4.3.7

【问题讨论】:

    标签: java hibernate jpa wildfly


    【解决方案1】:

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

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

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

    【讨论】:

    • 我尝试加入 fetch 但我还需要设置一个最大结果以限制返回结果集的大小。不幸的是,使用 join fetch 进行分页无法正常工作,因为休眠从 db 中选择所有内容并在内存中排序。
    • 请您尝试将@BatchSize 注释放在实体详细信息上,并在此处发布结果。在官方文档上说这也适用于实体级别link
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2013-06-21
      • 2019-03-28
      • 2013-09-20
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 2016-09-02
      • 2013-11-12
      • 1970-01-01
      相关资源
      最近更新 更多