1

我在 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中,它尝试解析 Car 属性Engine并发出另一个选择。

如果使用 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 似乎没有意识到它们是同一个关联的两端。从 Engine -> Car 中删除引用修复它,但如果我能在保留引用的同时让它工作,那就太好了。

4

1 回答 1

1

我认为您的问题与休眠中的错误有关。您可以检查那里发布的解决方法是否适合您。

错误报告

于 2013-02-08T09:05:20.067 回答