-->
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.  [ 10 posts ] 
Author Message
 Post subject: NullPointerException in SessionImpl.getOrphans()
PostPosted: Thu Feb 19, 2004 3:56 pm 
We are currently using Hibernate 2.1 with PostgreSQL 7.3.4 and JBoss 3.2.2. I am not including all mapping documents yet since I hope that the problem is clear from the description below.

I get a NullPointerException in SessionImpl.getOrphans() after vetoing an update in the Lifecycle method onUpdate() (see stack trace below). The broader situation is like this: We are using detached objects on the client, which are then sent to the EJB server to update the database. There was one problem with this approach: even detached objects that where not changed at all where updated by Hibernate, presumably because it can't really know. So we introduced a flag on our persistent objects that indicates if an update is needed. This flag is evaluated in Lifecycle.onUpdate() to veto the update when there are no changes. It is possible that persistent collections on such objects where actually changed, but their persistent data is stored in a different object which does get updated. It looked like this should elegantly solve all our problems, but now we are getting the NullPointerException.

Any ideas will be appreciated ;-)

Caused by: java.lang.NullPointerException
at net.sf.hibernate.impl.SessionImpl.getOrphans(SessionImpl.java:3123)
at net.sf.hibernate.engine.Cascades.deleteOrphans(Cascades.java:542)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:533)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1408)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1327)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1408)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1327)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1408)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1327)


Top
  
 
 Post subject:
PostPosted: Thu Feb 19, 2004 4:01 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Are you using 2.1.2?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 19, 2004 4:05 pm 
No, just 2.1 final. Should I switch?


Top
  
 
 Post subject:
PostPosted: Fri Feb 20, 2004 11:27 am 
Hm, I switched to 2.1.2 and now I get the following, seemingly unrelated problem:

java.lang.NullPointerException
at net.sf.hibernate.collection.PersistentCollection.forceInitialization(PersistentCollection.java:339)
at net.sf.hibernate.Hibernate.initialize(Hibernate.java:255)

The strange thing is that I do a successful Session.flush() right before this. Once again the object graph in question consists of detached objects that have been brought into a new session with Session.saveOrUpdate().


Top
  
 
 Post subject:
PostPosted: Fri Feb 20, 2004 12:44 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Code:
   public final void forceInitialization() throws HibernateException {
      if (initializing) throw new AssertionFailure("force initialize loading collection");
      if ( !session.isConnected() ) throw new HibernateException("disconnected session");
      if (!initialized) session.initializeCollection(this, false);
   }



The only way that an NPE could occur is if the collection is not associated with a session. So looks like your programming error.

Anyway, I will add another "check" in that method.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 11:52 am 
Regarding the second issue: is it possible that a veto in onUpdate() prevents a detached object from being brought into the session?


Top
  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 2:28 pm 
I can now confirm the above statement: vetoing the update of a cascaded object prevents its lazy loaded collections from being attached to the session on which saveOrUpdate() is called. I can see this in the debugger by looking at the object graph before and after the call to saveOrUpdate() in both cases: when the update is prevented the collections don't get a session, otherwise they do.

This happens on a object of class A which is within a collection owned by class B, and saveOrUpdate() is called on an instance of class B. The collection is lazy loaded with cascade=all. Class A has another lazy loaded collection of class C, and this collection's session stays null after the call to saveOrUpdate() if A vetoes the update.

I tried to reproduce the problem with just a few classes, simulating detached objects by simply closing their session, but the problem did not occur. Therefore I am wondering: is this a problem in my code or is it with Hibernate? This did not happen in Hibernate 2.1 final, it only came in Hibernate 2.1.2.

Once again I am grateful for any hint.


Top
  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 2:39 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Hmm interesting.

Add the following line to SessionImpl.doUpdateMutable():

Code:
if ( ( (Lifecycle) object ).onUpdate(this) ) {  // do callback
   log.debug("update vetoed by onUpdate()");
   reassociate(object, id, persister); //<---- New Line!
   return;
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 3:10 pm 
Looks like this solved the problem. Thanks!


Top
  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 6:07 pm 
Actually this might be responsible for another problem I now have in the following constellation:

Class A has a one-to-many collection of class B with cascade="all-delete-orphan", inverse="true". Class B has a many-to-one reference to class C, which in turn has a one-to-many collection of class B with cascade="all-delete-orphan", inverse="true".

The entire object graph consists of detached objects. I want to remove an instance of B by removing if from the collections in A and C. When I call saveOrUpdate(), the instance of C vetoes the update for application-specific reasons. This causes the operation to fail with
HibernateException: reassociated object has dirty collection (details below)

I do understand the general reason why this exception would be thrown, but I am not sure that it is appropriate in this case for 2 reasons:
1. The table containing C doesn't need to be updated, so no problem.
2. The collection has inverse="true", so it is not C's job to maintain it.

Are my arguments conclusive?

net.sf.hibernate.HibernateException: reassociated object has dirty collection
at net.sf.hibernate.impl.OnLockVisitor.processCollection(OnLockVisitor.java:47)
at net.sf.hibernate.impl.AbstractVisitor.processValue(AbstractVisitor.java:69)
at net.sf.hibernate.impl.AbstractVisitor.processValues(AbstractVisitor.java:36)
at net.sf.hibernate.impl.AbstractVisitor.process(AbstractVisitor.java:93)
at net.sf.hibernate.impl.SessionImpl.reassociate(SessionImpl.java:1654)
at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:1420)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1441)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1364)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:482)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1446)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1364)


Top
  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

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.