次のようにマッピングされた 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 は修正されますが、参照を維持しながらこれを機能させることができればいいと思います。