1

次のようにマッピングされた Car と Engine 間の双方向の 1 対 1 の関連付けがあります: (Hibernate 3.6 を使用)

<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();

すべての車を検索するために 1 つの選択を取得してから、見つかった各車に対して別の選択を取得します。

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=?
...

Engineロードされたそれぞれのプロパティを設定するときに、Hibernate が混乱するようです。ではTwoPhaseLoad.initializeEntity、 Car プロパティの解決を試み、Engine別の select を発行します。

setFetchMode の代わりに createAlias を使用すると、予想される単一選択が得られ、すべてが機能します。

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

これら 2 つの基準クエリは同じように動作するはずだという印象を受けました。マッピングで変更できるものはありますか? setFetchMode の代わりに createAlias を使用する必要がありますか?

更新:したがって、2 番目のクエリも適切ではありません。実際に Engine に参加し、後方参照のために Car に再​​び参加します。

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

休止状態が同じ関連付けの2つの端であることに気付いていないようです。Engine からの参照を削除 -> Car は修正されますが、参照を維持しながらこれを機能させることができればいいと思います。

4

1 に答える 1

1

あなたの質問は休止状態のバグに関連していると思います。そこに投稿された回避策が機能するかどうかを確認できます。

バグレポート

于 2013-02-08T09:05:20.067 に答える