2012-12-17 36 views
1

我有汽車和發動機之間的雙向one-to-one關聯映射如下:(與Hibernate 3.6)標準查詢 - 調用setFetchMode VS createAlias,n + 1個選擇

<class name="org.example.Car"> 
    <id column="id" name="PID"> 
     <generator class="uuid2" /> 
    </id> 
    <version name="Version" column="version" /> 

    <many-to-one cascade="all" name="Engine" not-null="true" unique="true" /> 
</class> 
<class name="org.example.Engine"> 
    <id column="id" name="PID"> 
     <generator class="uuid2" /> 
    </id> 
    <version name="Version" column="version" /> 

    <one-to-one cascade="all" name="Car" property-ref="Engine" /> 
</class> 

當我執行以下標準查詢加載所有小轎車和渴望獲取他們的引擎

session().createCriteria(Car.class) 
    .setFetchMode("Engine", FetchMode.JOIN) 
    .list(); 

我得到一個選擇找到所有汽車,然後又選擇每節車廂被發現:

select this_.id ... from Car this_ inner join Engine engine2_ on this_.Engine=engine2_.id 
select car0_.id ... from Car car0_ where car0_.engine=? 
select car0_.id ... from Car car0_ where car0_.engine=? 
select car0_.id ... from Car car0_ where car0_.engine=? 
... 

似乎Hibernate會在設置加載的每個Engine上的屬性時感到困惑。在TwoPhaseLoad.initializeEntity,它嘗試解決Engine上的Car屬性併發出另一個選擇。

如果使用createAlias而不是調用setFetchMode,我得到預期的單一選擇,一切工作:

session().createCriteria(Car.class) 
    .createAlias("Engine", "engine") 
    .list(); 

我的印象是,這兩個標準的查詢行爲應該是相同的。我的地圖中有什麼可以改變的地方嗎?我應該開始使用createAlias而不是setFetchMode嗎?

UPDATE:所以,第二個查詢也不好。它實際上是連接引擎,然後再加入汽車的反向參考:

select this._id ... from Car this_ 
    inner join Engine engine1_ on this_.engine=engine1_.id 
    left outer join Car car3_ on engine1_.id=car3_.engine 

它似乎並不像Hibernate實現他們是同一協會的2點結束。從引擎中刪除引用 - > Car修復了它,但如果我可以在保留引用的情況下使其工作,那將會很好。

回答

1

我認爲你的問題與hibernate中的bug有關。您可以檢查發佈的解決方法是否適合您。

Bug Report

+0

鏈接已死亡... – user2418306