-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: NullPointerException from CollectionPersister.recreate()
PostPosted: Thu Sep 25, 2003 9:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
I have no idea why this occurrs, and can't reseach this right now.

I have a bi-directional association which is non-cascadable in either direction. Transactions are handled through JTA.

Anyone have any ideas?

Mappings:
Code:
<class name="Enrollment" table="enrollment" proxy="IEnrollment">
    <id name="id" column="enroll_id"type="java.lang.Long" unsaved-value="null">
        <generator class="sequence"/>
    </id>
    ...
    <property
            name="status"
            type="EnrollmentStatusType"
            column="enroll_stat_id"
    />
    <many-to-one
            name="trainingClass"
            class="TrainingClass"
            cascade="none"
            outer-join="false"
            column="class_id"
    />
    ....
</class>

<class name="TrainingClass" table="class" proxy="ITrainingClass">
    <id name="id" column="class_id" type="java.lang.Long" unsaved-value="null">
        <generator class="sequence"/>
    </id>
    ...
    <property
            name="status"
            type="TrainingClassStatusType"
            column="class_stat_id"
    />
    <bag
            name="enrollments"
            lazy="true"
            inverse="true"
            cascade="none"
    >
        <key column="class_id" />
        <one-to-many class="Enrollment" />
    </bag>
    ...
</class>


Code:
Code:
    Session session = null;
    try
    {
        session = ...;
        ITrainingClass trainingClass = session.load(TrainingClass.class,trainingClassId);
        trainingClass.setStatus(TrainingClassStatus.CANCELLED);
        trainingClass.setDisplayable(false);

        for (Iterator itr = trainingClass.getEnrollments().iterator(); itr.hasNext(); )
        {
            final IEnrollment enrollment = (IEnrollment)itr.next();
            if (EnrollmentStatus.ENROLLED.equals( enrollment.getStatus() )
            || EnrollmentStatus.WAITLIST.equals( enrollment.getStatus() ))
            {
                enrollment.setStatus( EnrollmentStatus.PENDING );
                session.update( enrollment );
                session.flush();   // <--- here is where it complains
            }
        }

        session.update(trainingClass);
       session.flush();
    }
    ....
    finally
    {
        release(session);
    }


Exception:
Code:
java.lang.NullPointerException
   at net.sf.hibernate.collection.Set.entries(Set.java:251)
   at net.sf.hibernate.collection.CollectionPersister.recreate(CollectionPersister.java:655)
   at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2092)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2068)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2008)
   at com.vignette.it.apps.server.domain.mediators.EnrollmentMediator.update(EnrollmentMediator.java:264)
   at com.vignette.it.apps.server.domain.mediators.TrainingClassMediator.cancel(TrainingClassMediator.java:402)
...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 26, 2003 4:37 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Add an issue to JIRA, with a main() method. I have a funny feeling something like this might be fixed in the latest 2.1 CVS, however. So test against v21branch first.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 30, 2003 10:29 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Actually, in playing with the code driving this interaction some more I think I may have found a solution. It appears that calling session.update() against an entity already loaded by a session and bound to that session is not only not necessary, but just dangerous. Removing the session.update() calls seems to have fixed not only this issue, but some other subtle issues that we were encountering whic were hard to reproduce.

Following along the log messages, it seems that updating an entity using session.update() caused unintended (and really unexpected, as cascade was set to none and inverse set to true) deletion of collection further down the association tree.

But like I said, removing the session.update() seemed to solve the issue.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 30, 2003 10:57 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Steve I really don't believe you!

update() is a no-op in the case of an object already associated with the session.

perhaps you also removed the flush() call?

I don't actually understand why you were doing all those update()s and flush()s in the first place, but thats beside the point. You should not get an NPE.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 30, 2003 2:08 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
I don't actually understand why you were doing all those update()s and flush()s in the first place

This is all "collapsed" from DAO functionality. The actual processing is done in nested DAO calls. I simply wanted to reproduce the effects as closely as possible.

All my processing with the clients is done through DTOs, so all hibernate entity interaction is done within the bounds of a session. So as-is the update() calls are completely unnecessary. The only reason I was even using the updates was to hopefully leave open the option of shipping the entities out of session to the view at some point having the view manipulate the entities directly. The update() calls would be needed for that.

But as they are not now (and probably never in all actuality) needed, I just went ahead and removed them. This did fix the issue.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 6:36 am 
Regular
Regular

Joined: Mon Sep 08, 2003 4:53 am
Posts: 70
Location: Germany
Sorry for joining a discussion of two Hibernate pro's, but I think I got a similar behaviour, Steve described, a few days ago, using the Interceptor.

I have a class, with a collection, that is lazy. I load an object of this class, change a property (not the lazy collection) and flush the session. In Interceptor.onFlushDirty() the lazy collection is initialized.

This causes a deletion of collections further down the association tree as Steve described above.

If I load a second object of this class with the same Hibernate session, change a property and flush the session, than I get the NullPointerException as well.

Don't know, if it's the same problem, that Steve described, but it seems to be very similar to me.

Regards
Andreas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 6:40 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
This may be the case with me. I do use an interceptor and thought I went through great pains to not access collections if not already initialized. Perhaps I simply missed some case in my logic for verifying that state. What I saw in the logs was collection very, very far done the object hierarchy being deleted, so that sounds pretty similiar.

Removing the update calls did not fix this.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 6:43 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
andreas wrote:
In Interceptor.onFlushDirty() the lazy collection is initialized.



Aaiii! You can't do something like this in onFlushDirty()! This would completely screw up the state of the session. You must be very careful about things done during the flush().


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 6:59 am 
Regular
Regular

Joined: Mon Sep 08, 2003 4:53 am
Posts: 70
Location: Germany
What about a note in the Interceptor documentation, about this? I had to spent a few days and study hundreds of lines of log messages, till I had the idea, that initializing lazy collections in onFlushDirty causes my problems.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 7:10 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
There is a note about this in the docs for Interceptor.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 7:24 am 
Regular
Regular

Joined: Mon Sep 08, 2003 4:53 am
Posts: 70
Location: Germany
It is in the Javadoc, I see. What I meant is the online documentation chapter "7.10. Interceptors".

Next time I have to read the Javadoc as well as the online documention! Sorry.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 10:07 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
About the only time I can see this as an issue in my interceptor impl, is the case where the previous state of the collection was an un-initialized lazy collection and the current/new state is a brand new collection (ala the one-shot delete update to collections). There, the previous collection would be initialized so that I can determine which items were added/removed.

Would that scenario be disallowed under the restriction to not initialize lazy collections during flush in the Interceptor?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 10:59 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Really, don't ever initialize a collection or proxy from inside onFlushDirty()! The session is in a "delicate" state duing the flush process!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 01, 2003 9:03 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
OK, I have now rebuilt and redployed this app using the latest CVS snapshot of Hibernate2 (using the v21branch tag) and am still getting this error. But I am getting much more logging, so thats good.

I think I've discovered the cause of the issue, but cannot figure out why it would be an issue. As part of my Inteceptor chain on flushing dirty, I perform validations by opening a new session from the same session factory (using FlushMode.NEVER, and never calling flush). It is actually this parallel session which is somehow causing these headaches. What ends up happening, is that the seperate session performs queries and loads, but never any type of INSERT/DELETE/UPDATE. But as part of the calls on that seperate session, I see log messages like the following all over the logs:
Code:
2003-10-01 19:32:10,958 DEBUG [l.updateReachableCollection(SessionImpl.java:2800)] - Collection found: [com.vignette.it.apps.server.domain.entities.TrainingClass.scheduledInstructors#255337], was: [com.vignette.it.apps.server.domain.entities.TrainingClass.scheduledInstructors#255337]
2003-10-01 19:32:10,958 DEBUG [l.updateReachableCollection(SessionImpl.java:2800)] - Collection found: [com.vignette.it.apps.server.domain.entities.TrainingClass.enrollments#255337], was: [com.vignette.it.apps.server.domain.entities.TrainingClass.enrollments#255337]
2003-10-01 19:32:10,958 DEBUG [essionImpl.flushCollections(SessionImpl.java:2642)] - Processing unreferenced collections
2003-10-01 19:32:10,958 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.CourseVersion.materials#254295]
2003-10-01 19:32:10,958 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.CourseVersion.localizedSyllabusMap#254295]
2003-10-01 19:32:10,968 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.Course.qualifiedInstructors#254276]
2003-10-01 19:32:10,968 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.Course.relatedCourses#254276]
2003-10-01 19:32:10,968 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.Course.associatedTrainingProducts#254276]
2003-10-01 19:32:10,968 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.Course.tracks#254276]
2003-10-01 19:32:10,968 DEBUG [updateUnreachableCollection(SessionImpl.java:2852)] - Collection dereferenced: [com.vignette.it.apps.server.domain.entities.Course.notes#254276]
2003-10-01 19:32:10,968 DEBUG [essionImpl.flushCollections(SessionImpl.java:2653)] - Scheduling collection removes/(re)creates/updates
2003-10-01 19:32:10,978 DEBUG [SessionImpl.flushEverything(SessionImpl.java:2226)] - Flushed: 0 insertions, 1 updates, 0 deletions to 4 objects
2003-10-01 19:32:10,978 DEBUG [SessionImpl.flushEverything(SessionImpl.java:2231)] - Flushed: 0 (re)creations, 0 updates, 7 removals to 9 collections


Should opening this secondary session be a problem? We spoke about this a long time back (on the old forums) and the consensus then was that doing this was OK. Maybe thats changed now?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 02, 2003 4:35 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
Should opening this secondary session be a problem?


No, it should be fine. But make sure you don't associate any collections or proxies from the first session with the second.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.