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]