如果实体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,这就是为什么我想懒加载它们的原因(无需让hibernate使用单独的sql查询)。
那可能吗?如果是的话,我该怎么做?
谢谢弗朗兹
我已经解决了这个问题。
我所做的就是创建将字段EntityA#propertyB转换为名称为EntityA#propertyBs的Set的方法。但是我保留了EntityA#getPropertyB()和EntityA#setPropertyB(EntityB propertyB)访问器方法。
这些访问器方法的方法主体现在如下所示:
public EntityB getPropertyB() { return CollectionUtils.get(propertyBs, 0); } public void setPropertyBs(EntityB propertyB) { propertyBs= Collections.singleton(propertyB); }
然后在我的映射中,我映射了集合EntityA#propertyBs并指定对“字段”的访问。
<set name="scheduledAdInfos" lazy="true" fetch="subselect" access="field" cascade="none" inverse="true"> <key column="pk_a"/> <one-to-many class="EntityB"/> </set>
使用此设置,您现在可以创建从拥有的POJO(EntityA)到拥有的POJO(EntityB)的惰性映射,即使TABLE_B由TABLE_B拥有也是如此。