【问题标题】:JPA annotation criteria joinJPA 注释标准连接
【发布时间】:2016-01-19 09:29:53
【问题描述】:

我想知道如何强制 JPA 创建内部连接选择而不是 N+1 查询。我有一个使用 JPA 标准 API 的 通用 DAO,例如(简化):

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<T> pageQuery = cb.createQuery(genericType);
Root<T> root = pageQuery.from(genericType);     
pageQuery.select(root);     
TypedQuery<T> selectQuery = entityManager.createQuery(pageQuery);       
selectQuery.setFirstResult(0).setMaxResults(20);        
selectQuery.getResultList();

带有 JPA/Hibernate 注释的域实体可以包含其他实体,例如:

@ManyToOne(fetch=FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "arematcd")
public Matcode getMatcode() {
    return this.matcode;
}

我是否需要为当前类型的所有 FK 显式调用 root.fetch("propertyNameOfReferencedEntity");

编辑:

基于 Ish 建议的解决方法(只需将 JPA 替换为 Hibernate):

Session ss = entityManager.getSession();
Criteria pageQuery = ss.createCriteria(genericType);
pageQuery.setFirstResult(0).setMaxResults(20);      
pageQuery.list();

@ManyToOne 中设置optional=false 没有帮助。

【问题讨论】:

  • 使关系不可为空?那么我希望 JPA 实现会做 INNER,或者至少 DataNucleus JPA 会做。不知道“@Fetch”是什么,因为不是 JPA
  • @NeilStockton @Fetchorg.hibernate.annotations.Fetch 似乎没有效果,我尝试将nullable=false 添加到所有@JoinColumns 中父实体,但生成的查询仍然相同(虽然我没有更改数据库中列的可为空类型)
  • 我知道您使用特定于 JPA 的方式来构建您的 Criteria 查询。尝试使用 Hibernate 特定的 API 创建条件查询怎么样?不确定它是否会有所作为。也许,它将能够阅读此@Fetch(FetchMode.JOIN)
  • @Ish 刚刚尝试用 Hibernate 标准替换 JPA 标准,现在我有一个带有连接的选择,发布答案,我会接受它作为一种解决方法。
  • 很高兴它可以作为解决方法。刚刚发布了我的建议作为答案。谢谢!

标签: hibernate jpa


【解决方案1】:

由于您正在使用特定于 JPA 的方式来构建 Criteria 查询,因此可能会忽略 Hibernate 特定的注释,例如 @Fetch(FetchMode.JOIN)。所以我建议使用 Hibernate 特定的 Criteria API 构建您的查询。

目前,JPA 不像 Hibernate 那样支持特定类型的获取策略。 JPA 只有 LAZY 和 EAGER fetch。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多