Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtaining a new session from Hibernate for a background thread

I'm working on a web application. Usually at the beginning of a request (through the architecture code), a Hibernate session is opened to work with DB transactions. At the end of the request the session is closed. This works great for all of our transactions, except that in one particular instance, I want to fire a thread from a request. This thread will call DB transactions.

From the thread, I call "sessionFactory.openSession()", and with this session I perform my transactions. The problem arises in that when the request finishes, the thread itself may not necessarily be finished. So when the request finishes and the thread tries to perform another DB transaction I get a Hibernate Session is Closed! error.

Is there anyway that from my thread, I can open a "clean" session, not associated to the one opened at the start of the request?

like image 319
Jaime Garcia Avatar asked Nov 14 '22 12:11

Jaime Garcia


1 Answers

You can create an threading service, which extends HibernateAccessor, as a standalone Spring service, defined at spring.xml, and send to it code/data you want to process. Something like this:

    Session session = SessionFactoryUtils.getSession(
            getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());
    SessionHolder sessionHolder = null;
    try {
        applyFlushMode(session, false);
        sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
        Transaction t = getSessionFactory().getCurrentSession().beginTransaction();
        try {

            //execute your code here

            t.commit();
        } catch (Exception e) {
            t.rollback();
            log.error("Error", e);
        }
        try {
            flushIfNecessary(sessionHolder.getSession(), false);
        }
        catch (HibernateException ex) {
            throw convertHibernateAccessException(ex);
        }
    } finally {
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
        TransactionSynchronizationManager.unbindResource(getSessionFactory());
    }
like image 134
Igor Artamonov Avatar answered Dec 18 '22 08:12

Igor Artamonov