2015-10-20 89 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抓取。