问题描述
如果实体A具有与实体B的双向一对或零对一映射。
映射如下:
< class name =EntityAtable =TABLE_Amutable =truelazy =true>
< id name =idAtype =longcolumn =pk_aunsaved-value =null>
< generator class =sequence>
< param name =sequence> pk_a_seq< / param>
< / generator>
< / id>
< one-to-one name =propertyBclass =EntityBproperty-ref =propertyAconstrained =trueouter-join =false/>
< / class>
和
< class name =EntityBtable =TABLE_Bmutable =truelazy =true>
< id name =idBtype =longcolumn =pk_bunsaved-value =null>
< generator class =sequence>
< param name =sequence> pk_b_seq< / param>
< / generator>
< / id>
< / class>
当我为EntityA执行hql查询(或者更确切地说是一个命名的hql查询)时,hibernate急切地加载EntityA#propertyB带有单独的select语句。
我的问题是,如果我的hql返回1000个EntityA(它们都有自己的EntityB),hibernate会执行n + 1个查询(第一个查询将用于EntityA返回1000个结果,而n个查询将来自EntityA#propertyB select延迟加载)。
然而,我不需要那些EntityA#属性B的这就是为什么我想要懒惰加载它们(没有休眠使用单独的SQL查询)。
这可能吗?如果是这样,我该怎么做?
谢谢,
Franz
我所做的是将字段EntityA#propertyB转换为名称为EntityA# propertyBs。但我保留了EntityA#getPropertyB()和EntityA#setPropertyB(EntityB propertyB)访问器方法。
这些访问器方法的方法体现在如下所示: p>
public EntityB getPropertyB(){
return CollectionUtils.get(propertyBs,0);
}
public void setPropertyBs(EntityB propertyB){
propertyBs = Collections.singleton(propertyB);
}
然后在我的映射中,我映射了集合EntityA#propertyBs并指定了访问到'字段'。
< set name =scheduledAdInfoslazy =truefetch =subselectaccess =字段cascade =noneinverse =true>
< key column =pk_a/>
<一对多课程=EntityB/>
< / set>
使用此设置,您现在可以创建从拥有的POJO(EntityA)到拥有的惰性映射POJO(EntityB)即使TABLE_A归TABLE_B所有。
If have an entity A with a bidirectional one-or-zero-to-one mapping with entity B.
The mapping is as follows:
<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>
and
<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>
When I do an hql query (or rather, a named hql query) for EntityA, hibernate eagerly loads EntityA#propertyB with a separate select statement.
My problem with that is if my hql returns 1000 EntityA's (with all having their own respective EntityB's), hibernate will do n+1 queries (1st query would be for EntityA returning 1000 results, while the n queries would be coming from the EntityA#propertyB select lazy loading).
However, I do not need those EntityA#propertyB's that's why I want to lazy load them instead (without having hibernate use a separate sql query).
Is that possible? And if it is, how do I do that?
Thanks,Franz
I've fixed this problem.
What I did was to create turn the field EntityA#propertyB into a Set with the name EntityA#propertyBs. But I retained the EntityA#getPropertyB() and EntityA#setPropertyB(EntityB propertyB) accessor methods.
The method bodies of those accessor methods are now something like this:
public EntityB getPropertyB() {
return CollectionUtils.get(propertyBs, 0);
}
public void setPropertyBs(EntityB propertyB) {
propertyBs= Collections.singleton(propertyB);
}
Then in my mapping, I mapped the set EntityA#propertyBs and specify the access to 'field'.
<set name="scheduledAdInfos" lazy="true" fetch="subselect" access="field" cascade="none" inverse="true">
<key column="pk_a"/>
<one-to-many class="EntityB"/>
</set>
With this setup, you can now create a lazy mapping from the owning POJO (EntityA) to the owned POJO (EntityB) even if TABLE_A is owned by TABLE_B.
这篇关于如何通过hql延迟加载一对一的作文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!