【问题标题】:Criteria query - setFetchMode vs createAlias, n+1 selects条件查询 - setFetchMode 与 createAlias,n+1 选择
【发布时间】:2012-12-17 19:36:00
【问题描述】:

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

【问题讨论】:

    标签: hibernate hibernate-mapping criteria-api


    【解决方案1】:

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

    Bug Report

    【讨论】:

      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 2016-03-21
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多