2017-05-05 63 views
0

我已經樣品實體表A表B和在表A中,我們有註釋爲波紋管柱TABLE_B_ID:休眠標準OneToOne FetchType.Eager FetchMode.Join執行不必要queryes

@OneToOne(fetch = FetchType.EAGER, optional = false) 
@JoinColumn(name = "TABLE_B_ID") 
@Fetch(FetchMode.JOIN) 

然後,當我執行這樣簡單的代碼:

Criteria c = session.createCriteria(TableA.class); 
c.list(); 

爲N + 1次,其中n =數的排TableA中,即使表A已經與表B第一查詢joinned,休眠還是試圖通過另一種選擇,以獲得表B每個Hibernate的運行查詢查詢。

查詢觸發:

Hibernate: 
select 
    this_.id as id1_0_1_, 
    this_.name as name2_0_1_, 
    this_.TABLE_B_ID as TABLE_B_3_0_1_, 
    tableb2_.id as id1_1_0_, 
    tableb2_.name as name2_1_0_ 
from 
    TABLE_A this_ 
inner join 
    TABLE_B tableb2_ 
     on this_.TABLE_B_ID=tableb2_.id 
Hibernate: 
    select 
     tablea0_.id as id1_0_1_, 
     tablea0_.name as name2_0_1_, 
     tablea0_.TABLE_B_ID as TABLE_B_3_0_1_, 
     tableb1_.id as id1_1_0_, 
     tableb1_.name as name2_1_0_ 
    from 
     TABLE_A tablea0_ 
    inner join 
     TABLE_B tableb1_ 
      on tablea0_.TABLE_B_ID=tableb1_.id 
    where 
     tablea0_.TABLE_B_ID=? 
Hibernate: 
    select 
     tablea0_.id as id1_0_1_, 
     tablea0_.name as name2_0_1_, 
     tablea0_.TABLE_B_ID as TABLE_B_3_0_1_, 
     tableb1_.id as id1_1_0_, 
     tableb1_.name as name2_1_0_ 
    from 
     TABLE_A tablea0_ 
    inner join 
     TABLE_B tableb1_ 
      on tablea0_.TABLE_B_ID=tableb1_.id 
    where 
     tablea0_.TABLE_B_ID=? 

等..

我已經嘗試刪除FetchMode或更改optional=true但解僱查詢仍然是N + 1次。 甚至在他已經獲得第一個select查詢中的數據之後,hibernate發射另一個select的原因是什麼?

+0

您是否嘗試過使用FetchType.LAZY – Jens

+0

我想急於加載 – Angga

+0

您是否嘗試過使用內部/外部連接!可能是tableB比tableA多一行。 –

回答

0

你正在經歷一個衆所周知的問題,「N + 1個選擇」當你選擇一個父實體和休眠將使涉及與OneToOne家長孩子額外的選擇出現問題。所以如果你在數據庫中有「N」個父子記錄,hibernate會讓所有的父母有一個選擇,然後讓每個孩子分開選擇,從而產生總共N + 1個選擇。 有兩種方法爲「N + 1」的問題在Hibernate: 1.「加入取」所有OneToOne孩子。 2.啓用二級緩存並在OneToOne子項上使用@Cache批註。

你的問題是,你沒有「連接抓取」所有OneToOne孩子。你必須「加入」,包括可傳遞的孩子(從孩子自己或集合中引用的實體)。

製作OneToOne懶惰(因爲默認情況下它很渴望)只是部分解決方案,因爲只有當你訪問子節點上的某個getter時,hibernate纔會爲子節點選擇,但從長遠來看,它仍然會使所有N個選擇。

+0

這只是樣品臺,所以沒有像你提到的複雜性,你可以看到第一個加入應滿足所有需要的信息,所以這不是關於獲取問題。 @Cache也沒有工作。 – Angga