-->
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.  [ 7 posts ] 
Author Message
 Post subject: recovering from unique constraint violation on insert
PostPosted: Wed Jun 16, 2004 5:01 pm 
Newbie

Joined: Wed Jun 16, 2004 4:25 pm
Posts: 4
Hi

I've seen some questions similar to mine posted before, but haven't seen a solution that would meet the requirements of my problem.

I've got an application which used JDBC and is being refactored to use Hibernate.
One of the tables has a unique constraint defined on several fields.

The old JDBC code did the following:
Code:
   
   try {
      insert record     
   } catch (SQLException e) {
      if (... check in a DB dependent way whether the unique constraint failed ...) {
          modify existing record - NOT overrite existing record with new data!
           rather do something like UPDATE tbl SET field = field + ?  WHERE ...
      }
   }


I'd like to stress one more time - i don't care about a portable way of finding whether the unique constraint failed - i'm doing it in a DB dependent way.

When i'm trying to rewrite the above code snippet using Hibernate here's what happens:

Code:
        try {
          session.save(object); 
        } catch (HibernateException e) {
          Throwable cause = e.getCause();
          if (unique constraint violation occurred) {
           Object existingObject = session.createQuery("..").list().get(0);
           session.lock(existingObject, LockMode.UPGRADE);
           .. modify existing object (increase one of its fields values with a value that came as a parameter) ..
          }
        }


When the object already exists session.save(object) generates a HiberanteException, from its cause results that the unique constraint failed, so, an attempt is made to update the existing object. At the end of method execution when an attempt is made to commit the transaction the following error appears in the logs:
2004-06-16 22:21:41,257 ERROR [net.sf.hibernate.AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
net.sf.hibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs)
at net.sf.hibernate.impl.SessionImpl.checkId(SessionImpl.java:2605)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2429)
at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2422)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2224)
...
2004-06-16 22:21:41,259 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackLocalException in method: public abstract void com.ZManager.log(com.ZObject) throws com.ZException, causedBy:
net.sf.hibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs)
at net.sf.hibernate.impl.SessionImpl.checkId(SessionImpl.java:2605)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2429)


The exception message says don't flush the Session after an exception occurs. But i _want_ to recover in case an error occurs and i know how to do it with JDBC. Does anybody know how to implement the same functionality with Hibernate?

Thank u in advance,
Radu[/b]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 17, 2004 4:28 pm 
Newbie

Joined: Wed Jun 16, 2004 4:25 pm
Posts: 4
Hibernate versin: 2.1.4
MySQL: 4.x


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 17, 2004 4:53 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
try to retrieve a "clean" new hibernate session in your catch block.... but i don't really know if this is good

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 18, 2004 9:03 am 
Newbie

Joined: Wed Jun 16, 2004 4:25 pm
Posts: 4
Thank u for replying,

the problem with getting a "clean" Hibernate session is that the above code is part of an SLSB method with CMT... i could try getting a clean session but i'm concerned about the effects it might have on transaction managenet...

does anybody know a better solution?

thank u in advance,
radu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 28, 2004 10:41 am 
Newbie

Joined: Wed Jun 16, 2004 4:25 pm
Posts: 4
MySQL: 4.0.17
JBoss: 3.2.3


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 28, 2004 11:02 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Why would retreiving a new session have any effect on transaction management? I don't understand the concern here.

There is no better solution; a Hibernate session is unusable after usage of it results in an exception. It should immediately be closed and discarded.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 28, 2004 12:53 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Steve is right, your J2EE server will give to the new session the exact same JDBC connection in the exact same Tx context, so no problem.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.