hibernate LazyInitializing悖论

时间:2013-04-27 10:14:59

标签: java hibernate lazy-initialization

我有3个实体, Discipline DisciplineMembership DisciplineManagement

一个纪律有许多纪律成员
一个 Discipline 有许多 DisciplineManagements
DisciplineManagement DisciplineMembership 有一对一的关系

Discipline的相关hbm文件的相关部分如下所示:

Discipline.hbm

<class name="Discipline" table="DISCIPLINES">
    <id name="id" type="java.lang.Long">
        <generator class="increment" />
    </id>  

    <set name="memberships" inverse="false" cascade="all-delete-orphan" >
        <key column="disciplineId" not-null="true" />
        <one-to-many class="DisciplineMembership" />
    </set>  

    <set name="managements" inverse="false" cascade="all-delete-orphan">
        <key column="disciplineId" not-null="true" />
        <one-to-many class="DisciplineManagement" />
    </set>  

</class>

在一个名为 A 的函数中,我想迭代Discipline的DisciplineMemberships和DiscipilineManagements:

public void A(){
    Discipline discipline = this.getObject();
    for(DisciplineMembership mem: discipline.getMembers()){
        System.out.print(mem);
    }
    for(DisciplineManagement man: discipline.getManagements()){
        System.out.print(man);
    }
}

第一个 for 语句正确运行,但在第二个上,我按如下方式捕获LazyInitializationException:

13-04-27 13:54:26,115 [hibernate.LazyInitializationException (<init>:42)] ERROR: failed to lazily initialize a collection of role: Discipline.managements, no session or session was closed 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Discipline.managements, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
    at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
    at ObjectManagementPart_Edit.A(ObjectManagementPart_Edit.java:6)

我很困惑,这怎么可能?纪律会议是开放的,我可以遍历其成员资格,但是当我想通过它的管理进行迭代时,hibernate不能懒惰地初始化它们。

我该怎么办?

更新 我试图使用Hibernate.initialize()函数,所以函数A现在是这样的:

public void A(){
    Discipline discipline = this.getObject();
    Hibernate.initialize(discipline.getMembeships());
    for(DisciplineMembership mem: discipline.getMemberships()){
        System.out.print(mem);
    }
    Hibernate.initialize(discipline.getManagements());
    for(DisciplineManagement man: discipline.getManagements()){
        System.out.print(man);
    }
}

首次使用Hibernate.initialize()进行 Membeships 没有问题, 但在 Managements 的第二次使用中,我得到了这个例外:

org.hibernate.HibernateException: collection is not associated with any session
    at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474)
    at org.hibernate.Hibernate.initialize(Hibernate.java:431)
    at discipline.ObjectManagementPart_Edit.A(ObjectManagementPart_Edit.java:6)

现在我更加困惑:/

1 个答案:

答案 0 :(得分:1)

仅仅因为你可以迭代会员资格并没有告诉你它实际上只是让它们变得懒惰。如果之前加载的成员资格(会话开放的地方),他们就会受到影响。如果列表已经初始化,Hibernate.initialize(...)将不会执行任何操作。

要获得更精确的答案,您需要描述会话管理策略。 hibernate的大多数问题都源于会话管理不好的事实。

相关问题