GMsoF GMsoF - 2 months ago 25
Java Question

Hibernate - Could not obtain transaction-synchronized Session for current thread

I understand this question has been asked many time, but most can't explain my problem:

@RequestMapping("/testing")
public String testing(HttpServletRequest request, final ModelMap model)
{
Transaction ut = session.openSession().beginTransaction();

session.getCurrentSession(); // error here

ut.commit();

return "testing";
}


Why I am getting the error

Could not obtain transaction-synchronized Session for current thread.


If I annotate the method with
@Transactional
, it is working perfectly fine. Because I have
@EnableTransactionManagement
in my spring context.

I want to try something to understand the difference between
getCurrentSession
and
openSession
, so I created test case above.

getCurrentSession
is called within a active Transaction context, why it is still throwing me error???

Refer the code from this.

Answer

OK, after so long time of research, I found out I have miss out the paragraph below:

You will not see these code snippets in a regular application; fatal (system) exceptions should always be caught at the "top". In other words, the code that executes Hibernate calls in the persistence layer, and the code that handles RuntimeException (and usually can only clean up and exit), are in different layers. The current context management by Hibernate can significantly simplify this design by accessing a SessionFactory. Exception handling is discussed later in this chapter.

So the example showing there indeed will not be working in regular scenario...

I have to do as below:

// BMT idiom with getCurrentSession()
try {
    UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");

    tx.begin();

    // Do some work on Session bound to transaction
    factory.getCurrentSession().load(...);
    factory.getCurrentSession().persist(...);

    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}

Which mean, the usage of getCurrentSession is pretty restricted, it must be running in a active (and specific) transaction.

Comments