2016-04-22 190 views
3

我有一個@ManyToOne關係的實體,我想用一個查詢檢索,因此使用@Fetch(FetchMode.JOIN)。有時Hibernate不尊重並且發佈N + 1 SELECT s。 有時我的意思是,因爲我不知道是什麼觸發它,我有案件在同一類不同的查詢這可能發生與否。爲什麼Hibernate有時會忽略FetchMode.JOIN?

這是我使用的註釋簡化實體:

@Entity 
public class Employee { 

    @ManyToOne 
    @Fetch(FetchMode.JOIN) 
    private Department department; 

} 

隨着

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class); 

Root<Employee> root = criteriqQuery.from(Employee.class); 

TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery); 

List<Employee> employees = typedQuery.getResultList(); 

我希望單個查詢來獲取兩個Employee及其Department,像

select ... from Employee join Department on ... 

而是我得到第一個選擇所有N Employee s,然後N SELECT s對所有Department s(考慮無緩存)。

我發現了很多類似的問題,但他們的答案提示瞭解決方法,並沒有解釋爲什麼會發生這種情況。請避免提示使用延遲加載的答案:這不是我要求的。

回答

5

規則很簡單:查詢忽略提取模式。當你寫一個查詢時,你告訴什麼是加入的,什麼是未加入的。

只有當實體加載了像EntityManager.find(class, id)這樣的方法時,或者在瀏覽某個其他實體圖並加載其關聯時,纔會考慮提取模式。

+0

謝謝!就是這樣:Criteria API忽略'@ Fetch',但使用'Root.fetch()'(這是JPA)我可以達到相同的結果。 –