2010-12-02 22 views
2

分組時,我有一個Hibernate條件對象,我建立正是如此:防止休眠N + 1選擇由實體

Criteria obsCriteria = hibernateTemplate.getSessionFactory() 
    .getCurrentSession().createCriteria(Observation.class); 

ProjectionList projection = Projections.projectionList() 
    .add(Projections.rowCount()) 
    .add(Projections.avg("value").as("avgScore")) 
    .add(Projections.avg("type.score")) 
    .add(Projections.max("date")) 
    .add(Projections.groupProperty("observedSubject")); 
criteria.setProjection(projection); 

這產生了正確的結果對我來說,但「observedSubject」屬性是一個實體。當我將show_sql設置爲true時,我看到在第一個查詢(返回了18行)之後,有18個選擇來獲取observableSubject實體。我試過了:

criteria.setFetchMode("observedSubject", FetchMode.JOIN); 

但是沒有奏效。作爲一種在黑暗中刺,我試過:

criteria.createAlias("observedSubject", "observedSubject", Criteria.FULL_JOIN); 

但這並沒有工作,無論是。有什麼辦法可以防止這種行爲?

回答

0

您是否註釋observedSubjectFetchType.LAZY?如果沒有,Hibernate正在恢復默認行爲,即獲取EAGER

如果希望孩子獲取聯想在運行時,但你不想爲每個協會單獨SELECT電話,對聯想設置@BatchSize,Hibernate會批SELECT調用,使事情更加有效。

+0

謝謝你在回答這個不愉快的問題。我確實需要ObservedSubject中的數據 - 這就是爲什麼它被添加到投影列表中。我試過了你建議的@BatchSize註釋,但是我不認爲它會應用於這樣的使用Criteria API的查詢嗎?我想到的一種方法是創建一個包含我想要的所有連接(包括來自被觀察主題的字段)和基於該視圖創建不可變實體的視圖。這樣可以節省N + 1個查詢,但它與我以前嘗試的並不很接近,所以我仍然在想是否有辦法做到這一點。 – jhericks 2011-07-25 18:40:18