2

I am using jersey with mysql and hibernate 4 and c3p0. I have created a initialization servlet that configures hibernate and sets the current session context class to thread. I have created hibernateUtils class that contains static methods for getting and committing sessions and I am using a filter to start a session on inbound request and commit it upon response.

The problem is that at some random intervals I am getting org.hibernate.TransactionException: nested transactions not supported exception, but I am not trying to create a new session except on the filter.

Correct me if I am wrong but when setting the current session class to thread I don't need to create a threadlocal in the hibernateutil, hibernate does this. So my question is, is this a safe way to handle that and what could cause the error happening on random intervals?

====================== EDIT ===========================

Sorry for not posting the code earlier. So the filter implements the ContainerRequestFilter,ContainerResponseFilter

in the request filter I am doing

Session session = sessionfactory.getCurrentSession();
session.getTransaction().begin();
session.setDefaultReadOnly(readOnly);

and in the response

Transaction transaction = sessionfactory.getCurrentSession().getTransaction();
try {
    if (transaction != null && !transaction.wasCommitted()
       && !transaction.wasRolledBack() && transaction.isActive()) {
        transaction.commit();
    }
} catch (HibernateException e) {
    Transaction transaction = sessionfactory.getCurrentSession().getTransaction();
    try {
        if (transaction != null && transaction.isActive()) {
            transaction.rollback();
        }
    } catch (HibernateException e) {

    } finally {
         Session session = sessionfactory.getCurrentSession();
         try {
              if (session != null && session.isOpen()) {
                  session.close();
              }
         } catch (HibernateException e) {
            log.error("Closing session after rollback error: ", e);
            throw e;
     }

}

1
  • can you post the stacktrace of the error ? and the code of your filter ? Commented Sep 12, 2013 at 20:40

1 Answer 1

1

It seems that you are using programmatic transaction demarcation in your filter (as far as I understood). So please double check that you terminate properly each transaction, nevermind what append during the request (i.e. rollback if you get an exception and commit otherwise) :

try {
    session.getTransaction().begin();
    // call the filter chain
    session.getTransaction().commit()
}
catch (RuntimeException e) {
    session.getTransaction().rollback();
}

Without the code it's difficult to be sure, but I guess that for some request you didn't terminate the transaction properly (i.e. by a commit or by a rollback). So the transaction remains associated to the thread and the thread go back to the thread pool (in a very strange state since there is still a transaction associated with it), then another request reuse the same thread, a new transaction is created in the filter... and you got the exception.

EDIT

After looking carrefully at your code, it (may) confirms my assumptions.

Look at the flow when transaction.wasRolledBack()==true : it won't be commited nor rolled back.

And if you the javadoc for Transaction.wasRolledBack() :

Was this transaction rolled back or set to rollback only?

If the transaction is marked as "RollBack only" : it will return true, but it don't means that the transaction is ended. It means that the only possible ending state for the transaction is "RollBack".

But, on the other hand the same javadoc also say this:

Returns: boolean True if the transaction was rolled back via this local transaction; false otherwise.

I found that ambiguous.

So I suggest you to do this:

if (transaction != null && !transaction.wasCommitted()
   && !transaction.wasRolledBack() && transaction.isActive()) {
    transaction.commit();
}else if(transaction.wasRolledBack()){
    transaction.rollback();
}
Sign up to request clarification or add additional context in comments.

2 Comments

sorry for not posting sample code prior, I have updated my question I know that it seems that way but I cannot think of where the leaked session can be since I am closing it on finally!
thank you for this tip, I will try and see if the error persists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.