2017-08-16 51 views
0

所以這裏是我的問題:休眠 - 實體的投影和取物策略

我有2個人類和部門。

人:

@Entity 
public class Personne 
{ 
    @Id 
    private Long id; 

    private String name; 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="dept_id") 
    @Fetch(FetchMode.JOIN) 
    private Departement dept; 


    // getter & setter 
} 

部:

@Entity 
public class Departement 
{ 
    @Id 
    private Long id; 

    private String name; 

    // getter & setter 

} 

我想選擇一個personn只DEPARTEMENT與條件查詢,所以我使用的投影:

我代碼:

Criteria crt = session.createCriteria(Personne.class); 
      crt.createAlias("dept", "d",JoinType.LEFT_OUTER_JOIN); 
      crt.setProjection(Projections.projectionList().add(Projections.property("dept"))); 
      crt.add(Restrictions.eq("id", 1L)); 

以上查詢效果很好,但我得到2個查詢,而我期望只有1,因爲我的提取類型是渴望。

日誌:

[use] 2017-08-16 16:23:07,113 DEBUG [main] SqlStatementLogger.logStatement(109) | select this_.dept_id as y0_ from Personne this_ left outer join Departement d1_ on this_.dept_id=d1_.id where this_.id=? 
[use] 2017-08-16 16:23:07,119 DEBUG [main] SqlStatementLogger.logStatement(109) | select departemen0_.id as id1_0_0_, departemen0_.name as name2_0_0_ from Departement departemen0_ where departemen0_.id=? 

似乎實體火災n + 1個選擇的那個投影。那有意義嗎?

任何人都可以幫助我嗎?

感謝

+0

我認爲你必須做一個系統輸出或者在強制休眠來觸發第二個查詢的條件執行之後做別的事情。你可以在session.createCriteria(...)方法之後顯示完整的代碼嗎? –

+0

@MadhusudanaReddySunnapu,你的回覆,不,我只是'crt.list();'這個代碼後沒有更多。 –

+0

如果您在映射上刪除了@ @CollectionColumn和@Fetch'註解,會發生什麼? – Naros

回答

0

EAGER並不意味着更少的查詢將被執行,只有當業主實體被查詢的查詢將被執行。

你可以使用的是@FetchMode註釋,在你的情況下,我會假設你想要一個FetchMode.JOIN

FechtMode的javadoc:https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/FetchMode.html

無論哪種方式,要小心的結果,請他深入討論瞭如何抓取模式工作檢查從FetchMode Join vs SubSelect的gabrielgiussi答案。

+0

謝謝你的回覆,但是我已經在FetchMode.JOIN中使用了@FetchMode註解,並且我期待它在獲取personn的時候獲得一個外連接,但它不會。 –

+0

哦對不起,我的錯誤,我完全誤解了它 –

+0

但是,如果你已經有獲取類型和一切,你不需要做crt.setProjection(Projections.projectionList()。add(Projections)。財產(「部」))),它將已經帶來的查詢 –