-->
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.  [ 1 post ] 
Author Message
 Post subject: hibernate 2.1 rolling back generated identity values
PostPosted: Sun Apr 02, 2006 11:09 pm 
Newbie

Joined: Sun Apr 02, 2006 9:49 pm
Posts: 1
I am working with hibernate 2.1 and am having an issue with successfully rolling back objects generated identifier values when a transaction rolls back.

I should mention that our system uses "short-lived/fleeting" sessions, only performing work within a transaction when abosolutely neccessary.

I will explain what my goal is at a high level first.

Our system has several points at which it validates the state of persisted objects. One of those points, which we call "Save" began causing us grief when it came to reusing objects (that are maintained using a wizard on the client) that failed validation in this "Save" step.

So we have an object that has some invalid state that we do not want to persist to the store, but we are already inside our transaction. When the system finds this object is invalid, it throws a runtime exception that is gracefully handled, and the transaction is rolled back. As mentioned, our original problem was that any objects saved within the transaction so far will retain their generated ids and concurrency values (which is not correct). Unfortunately hibernate leaves the rolling back of these values to the developer, which wasn't too much hassle to implement.

Everything seems to work correctly in our codebase up until a certain point. One of the objects that is to be flushed is a newly created object, and therefore will have a identifier value of null initially. It has several one-to-many collections mapped.

The transaction rolls back, and our system reassigns all the objects identifier values and concurrency values to a snapshot taken before the save was attempted. From debugging, I can see all of the objects are in a state which we want them after the rollback. When the incorrect data is reentered correctly by the user, and the system attempts to save the objects again (this time using identifier values taken prior to the first save), hibernate is throwing the following exception.

Code:
Caused by: net.sf.hibernate.HibernateException: Don't dereferemce a collection with cascade="all-delete-orphan": com.initech.core.Order.orderItems
   at net.sf.hibernate.impl.SessionImpl.prepareCollectionForUpdate(SessionImpl.java:3002)
   at net.sf.hibernate.impl.SessionImpl.updateReachableCollection(SessionImpl.java:2939)
   at net.sf.hibernate.impl.FlushVisitor.processCollection(FlushVisitor.java:32)
   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.SessionImpl.flushEntity(SessionImpl.java:2637)
   at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2503)
   at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2298)
   at net.sf.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1821)
   at net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1578)
   at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1543)
   at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:49)
   at au.com.essential.mansys.bl.LimitedQueryCallback.executeQuery(AbstractSpringHibernateDao.java:1303)
   at au.com.essential.mansys.bl.LimitedNamedQueryCallback.doInHibernate(AbstractSpringHibernateDao.java:1315)
   at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:312)
   ... 50 more


Looking at the source, and attaching and debugging it I can see that hibernate is attempting to prepare flushing the one-to-many mapped collection (which incidentally contains no objects).

Code:
      if ( entry.loadedPersister!=null || entry.currentPersister!=null               ) {                    // it is or was referenced _somewhere_

         if (
            entry.loadedPersister!=entry.currentPersister ||                                // if either its role changed,
            !entry.currentPersister.getKeyType().equals(entry.loadedKey, entry.currentKey)  // or its key changed (for nested collections)
         ) {

            // do a check
            if (
               entry.loadedPersister!=null &&
               entry.currentPersister!=null &&
               entry.loadedPersister.hasOrphanDelete()
            ) {
               throw new HibernateException("Don't dereferemce a collection with cascade=\"all-delete-orphan\": " + coll.getCollectionSnapshot().getRole());
            }


The exception is getting thrown at the bottom of the source above, it seems because the entry.loadedKey value is different from the entry.currentKey value. I am unsure as to how I can work around this requirement that those two values are equal. Another strange thing is that the loadedKey value is the next identifier value from the sequence in the table, and the currentKey value is the one after that.

It seems here that hibernates inner workings (the second level cache maybe) are remembering the previously assigned and generated identifier value and the snapshot isnt getting pushed down deep enought for the comparison to return true.

Does anyone know what could be happening here?


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

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.