hibernate急切地加载一个通常很懒的关联

时间:2010-08-21 09:52:14

标签: java hibernate

我有这两个映射:

<hibernate-mapping>
    <class name="sample.Operator" table="OPERATOR">
        <id name="id" >
            <generator class="native" />
        </id>
        <property name="name"  not-null="true">
            <column name="NAME" />
        </property>
        <set name="pointCodes" inverse="false" lazy="true" cascade="save-update">
            <key>
                <column name="OperatorID" />
            </key>
            <one-to-many class="sample.PointCode" />
        </set>
    </class>

<hibernate-mapping>
 <class name="sample.PointCode" table="POINTCODE">
  <id name="id">
   <generator class="native" />
  </id>
  <properties name="pointCodeKey" unique="true">
   <property name="pointCode" not-null="true">
   </property>
   <property name="networkIndicator" not-null="true">
   </property>
  </properties>
  <property name="name" not-null="true">
  </property>
 </class>
  </hibernate-mapping>

大多数情况下,当一个操作符进行操作时,我希望laCily获取pointCodes,所以我不想在映射中设置lazy =“false”,

但我有一个查询,例如session.createQuery("from Operator").list()我想让pointCodes关联懒得获取 - 我该怎么做?

2 个答案:

答案 0 :(得分:3)

hibernate参考手册writes

  

“获取”连接允许关联或   价值集合   与父母一起初始化   使用单个选择的对象。这是   在a的情况下特别有用   采集。它有效地覆盖了   外连接和延迟声明   关联的映射文件   和收藏品。见第20.1节,   “获取策略”了解更多   信息。

from Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens
     

通常不需要获取提取连接   分配一个别名,因为   不应使用关联对象   在where子句(或任何其他   条款)。相关的对象是   也没有直接退回   查询结果。相反,他们可能是   通过父对象访问。该   只有你可能需要别名的原因是   如果你以递归方式连接取一个   进一步收集:

from Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens child
    left join fetch child.kittens
     

不能使用fetch构造   使用iterate()调用的查询(但是   可以使用scroll())。抓取应该是   与setMaxResults()或。一起使用   setFirstResult(),作为这些操作   基于结果行   通常包含重复的渴望   集合提取,因此,数量   行不是你所期望的。   Fetch也不应该一起使用   有条件的即兴。它是   可以创建一个笛卡尔积   通过join获取多个   在查询中收集,所以要小心   这个案例。加入获取多个   集合角色可以产生   袋映射的意外结果,   因此,建议用户自行决定   在这种情况下制定查询。   最后,请注意完全加入fetch和   右连接获取没有意义。

答案 1 :(得分:0)

仅仅为了参考,我遇到过类似这样的事情,hibernate总是热切地为我加载一套。

原来我有这个二传手:

public void setStreams(Set<StreamRef> streams) {
  for (StreamRef s : (Set<StreamRef>) streams) {
    s.setTape(this); // boo on hibernate, which apparently needs this. whoa!
  }
this.streams = streams;
}

这是由hibernate调用的(将它传递给一个惰性集的指针)但是然后我的for循环基本上是在那时调用它来加载它。如果这有助于任何粉丝:)

您可以通过关闭会话来测试它是否是懒惰的,然后尝试迭代集合。如果它很懒,你就会得到org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: XX.streams, no session or session was closed