开发者

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 sessio开发者_开发知识库n 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?


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());
    }


You can use JPA Entity Manager to begin and commit transactions manually. Here is my extended answer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜