2

I have 3 Entities named, Discipline, DisciplineMembership, DisciplineManagement:

one Discipline has many DisciplineMemberships
one Discipline has many DisciplineManagements
a DisciplineManagement has one to one relation with DisciplineMembership

the related part of associated hbm file for Discipline looks like this:

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>

in a function called A, I want to iterate over DisciplineMemberships and DiscipilineManagements of a Discipline:

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);
    }
}

first for statement runs correctly, but on second one, I catch LazyInitializationException as follows:

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)

I am confused how can this be possible? the Discipline Session is open, I can iterate through its memberships, but when I want to Iterate through its managements, hibernate can not lazyInitialize them.

what should I do?

UPDaTE: I tried to use Hibernate.initialize() function, so the function A is now like this:

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);
    }
}

the first use of Hibernate.initialize() for Membeships has no problem, but in second use for Managements I get this exception:

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)

Now I am more Confused :/

7
  • what should you do? don't be lazy, fetch eager. Commented Apr 27, 2013 at 10:17
  • 1
    No :D I do not want to erase the problem, Commented Apr 27, 2013 at 10:19
  • I have an idea if you put some annotation or the flag to not to go for the collection or just return the empty collection so you don't need to initialize it naturally when you traverse the tree. Commented Apr 27, 2013 at 10:24
  • 1
    Are you sure the session is open? Is it the session you loaded the discipline in? What does this.getObject do? Commented Apr 27, 2013 at 10:40
  • 1
    Everything points to: you have already loaded discipline.getMemberships() but not discipline.getManagements() (and the Session was closed) when you call that A() method. Try this: make sure you get/send a reference of the Session in/to A(), and, before (or inside) each for loop, do a System.out.println(session.isOpen());. This will solve, or at least narrow down, the problem. Commented Apr 27, 2013 at 21:00

1 Answer 1

1

Just because you can iterate over memberships does not tell you that it actually just fetched them lazy. If the memberships where loaded before (where the session was open) they are keept. Hibernate.initialize(...) will not do anything if the list was already initialised.

For a more precise answer, you need to describe your session management strategy. Most problems with hibernate are rooted in the fact that the session management is not good.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.