【发布时间】:2010-11-01 04:36:49
【问题描述】:
如果实体 A 与实体 B 具有双向一对一或零对一映射。
映射如下:
<class name="EntityA" table="TABLE_A" mutable="true" lazy="true">
<id name="idA" type="long" column="pk_a" unsaved-value="null">
<generator class="sequence">
<param name="sequence">pk_a_seq</param>
</generator>
</id>
<one-to-one name="propertyB" class="EntityB" property-ref="propertyA" constrained="true" outer-join="false"/>
</class>
和
<class name="EntityB" table="TABLE_B" mutable="true" lazy="true">
<id name="idB" type="long" column="pk_b" unsaved-value="null">
<generator class="sequence">
<param name="sequence">pk_b_seq</param>
</generator>
</id>
<many-to-one name="propertyA" class="EntityA" not-null="true" unique="true" lazy="proxy" column="fk_a"/>
</class>
当我为 EntityA 执行 hql 查询(或者更确切地说是命名的 hql 查询)时,hibernate 会急切地使用单独的 select 语句加载 EntityA#propertyB。
我的问题是,如果我的 hql 返回 1000 个 EntityA(都有各自的 EntityB),hibernate 将执行 n+1 个查询(第一个查询是 EntityA 返回 1000 个结果,而 n 个查询将来自EntityA#propertyB 选择延迟加载)。
但是,我不需要那些 EntityA#propertyB,这就是为什么我想延迟加载它们(不让休眠使用单独的 sql 查询)。
这可能吗?如果是,我该怎么做?
谢谢, 弗朗茨
【问题讨论】:
-
我不完全理解问题所在。如果您为一组 EntityA 执行 hql,则每当您调用代理方法 EntityA.getPropertyB() 时,将通过单独的查询加载相应的 EntityA#propertyB。这是正常的延迟加载行为。您到底希望行为是什么?
-
问题是因为我的 query.list() 得到了 n+1。根据我的调查,有两个原因:a.) 当我执行 session.getNamedQuery("myQueryString").
.list() 时,Hibernate 急切地返回所有匹配的 EntityA 及其 EntityA#getPropertyB()初始化。 b.) EntityA#getPropertyB() 通过单独的 select 语句进行初始化。因此,使用一个 query.list(),我已经遇到了 n+1 问题。如果我可以删除 (a.) 或 (b.),那么我将能够解决我的 n+1。最好,我可以删除 (a.)
标签: hibernate hql lazy-loading one-to-one many-to-one