2015-10-20 90 views
0

我想知道如何强制JPA创建内部联接选择而不是N + 1查询。我有一个通用 DAO使用JPA标准API一样(简体):JPA注释条件加入

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; 
} 

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

编辑:

解决方法基于伊什的建议(只是用Hibernate取代JPA):

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

设置在@ManyToOneoptional=false没有帮助。

+0

使关系不可为空?那么我会期待JPA实现INNER,或者至少DataNucleus JPA。不知道什么是“@Fetch”,因为不是JPA –

+0

@NeilStockton'@ Fetch'是_org.hibernate.annotations.Fetch_它似乎没有效果,我试图给所有'@ JoinColumn'添加'nullable = false'在一个父实体,但生成的查询仍然是相同的(我没有改变列中的数据库的可空类型) – mota

+0

我知道你使用JPA特定的方式来构建你的Criteria查询。如何尝试使用Hibernate特定API创建标准查询?不知道它是否会有所作为。也许,它将能够阅读这个'@Fetch(FetchMode.JOIN)' – Ish

回答

0

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

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