0

I'm trying to save data using Hibernate. Everything happens within the same session. The logic is following :

1) Begin a transaction and try to save :

try
{

  session.getTransaction().begin();
  session.save(result);
  session.getTransaction().commit();
}
catch (Exception e)
{
  session.getTransaction().rollback();
  throw e;
}

2) If a new record violates integrity constraint catch an exception in the outer wrapper method, open another transaction and query more data

catch (ConstraintViolationException e)
{
  if ("23000".equals(e.getSQLException().getSQLState()))
  {
    ...

    session.getTransaction().begin();
    Query query = session.createQuery("from Appointment a where a.begin >= :begin and a.end <= :end");
    query.setDate("begin", date);
    query.setDate("end", DateUtils.addDays(date, 1));

    List results = query.list();
    session.getTransaction().commit();

The problem is when the second transaction performs query.list it throws an exception that should'be been linked with the previous transaction.

SQLIntegrityConstraintViolationException: ORA-00001: unique constraint

Should I query data from another session or what's the other way to isolate two transactions from each other?

Thanks!

andreybavt
  • 1,301
  • 4
  • 17
  • 32
  • i guess in the 2nd case you will have to rollback the first transaction in the catch block when the exception is thrown and later query for the 2nd transaction. currently you are just starting the 2nd transaction when on error as the 1st is not still rolled back – vikeng21 Oct 06 '14 at 04:42
  • @vikeng21, not really, The first block has it's own "catch (Exception e)" and it rolls back the first transaction. Then it re-throws an exception, it's caught by the second block and a second transaction is started. – andreybavt Oct 06 '14 at 04:47
  • oh ok so they are the same part of the code but your exception hirerchy is not correct and your session object is global right. can you try creating a new session object as for every transaction we can create a session object. also your exception looks like insertion related but you are actually running a select query not sure why you are getting it – vikeng21 Oct 06 '14 at 04:56
  • Sure, that's what my concern is about! The second query is select, but not only it throws an "insert-related" exception, this exception is actually coming from the first transaction. I not so sure that creating a new session for each transaction is a good design approach, maybe I'm wrong... – andreybavt Oct 06 '14 at 05:07

3 Answers3

1

You should not use the same session if you get an exception, you have to close the session and use a different session for your second operation. This is given in hibernate documentation:

13.2.3 Exception Handling

If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.

Chaitanya
  • 15,403
  • 35
  • 96
  • 137
0

Hope the Exception class is base for all types of exceptions, hence if it is placed before it will be catched always and rest of the exception handling is isolated.

  • In the debugger I really stepped first in the `catch (Exception e) { session.getTransaction().rollback(); throw e; } ` block and then in the second ` catch (ConstraintViolationException e)` block. So all of the code I mentioned is reachable. The problem is the scope of each transaction and why it's all mixed – andreybavt Oct 06 '14 at 05:07
0

Can you try to replce session.save() with session.persist method, hope this might resolve your problem. Refer following link for more details about both methods.

What's the advantage of persist() vs save() in Hibernate?

Community
  • 1
  • 1