我在Car和Engine之间有一个双向的一对一关联,映射如下:(使用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();
我得到一个选择以查找所有汽车,然后为找到的每辆汽车选择另一个:
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
中,它会尝试解析Engine
上的Car属性并发出另一个选择。
如果使用createAlias而不是setFetchMode,我会得到预期的单选,一切正常:
session().createCriteria(Car.class)
.createAlias("Engine", "engine")
.list();
我认为这两个标准查询的行为应该相同。我的映射中是否可以更改某些内容?我应该开始使用createAlias而不是setFetchMode吗?
更新:因此,第二个查询也不好。它实际上加入了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
似乎hibernate并不意识到它们是同一个关联的两端。从引擎中删除引用 - &gt;汽车修理它,但如果我能在保持参考的同时使其工作,那将是很好的。