org.riotfamily.common.hibernate.ThreadBoundHibernateTemplate.java Source code

Java tutorial

Introduction

Here is the source code for org.riotfamily.common.hibernate.ThreadBoundHibernateTemplate.java

Source

/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.riotfamily.common.hibernate;

import java.sql.SQLException;

import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;

/**
 * Subclass of {@link HibernateTemplate} that binds the Hibernate Session to
 * the current thread.
 */
public class ThreadBoundHibernateTemplate extends HibernateTemplate {

    private Logger log = LoggerFactory.getLogger(ThreadBoundHibernateTemplate.class);

    public ThreadBoundHibernateTemplate() {
        super();
    }

    public ThreadBoundHibernateTemplate(SessionFactory sessionFactory, boolean allowCreate) {
        super(sessionFactory, allowCreate);
    }

    public ThreadBoundHibernateTemplate(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    @Override
    protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession)
            throws DataAccessException {

        Assert.notNull(action, "Callback object must not be null");

        Session oldSession = null;
        Session session = (enforceNewSession
                ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor())
                : getSession());

        SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
                .getResource(getSessionFactory());

        boolean existingTransaction = !enforceNewSession
                && (!isAllowCreate() || (sessionHolder != null && sessionHolder.containsSession(session)));

        if (existingTransaction) {
            log.debug("Found thread-bound Session for LongConversationTemplate");
        } else {
            if (sessionHolder != null) {
                oldSession = sessionHolder.getSession();
                sessionHolder.addSession(session);
            } else {
                TransactionSynchronizationManager.bindResource(getSessionFactory(), new SessionHolder(session));
            }
        }

        FlushMode previousFlushMode = null;
        try {
            previousFlushMode = applyFlushMode(session, existingTransaction);
            enableFilters(session);
            Session sessionToExpose = (enforceNativeSession || isExposeNativeSession() ? session
                    : createSessionProxy(session));
            Object result = action.doInHibernate(sessionToExpose);
            flushIfNecessary(session, existingTransaction);
            return result;
        } catch (HibernateException ex) {
            throw convertHibernateAccessException(ex);
        } catch (SQLException ex) {
            throw convertJdbcAccessException(ex);
        } catch (RuntimeException ex) {
            // Callback code threw application exception...
            throw ex;
        } finally {
            if (existingTransaction) {
                log.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
                disableFilters(session);
                if (previousFlushMode != null) {
                    session.setFlushMode(previousFlushMode);
                }
            } else {
                SessionFactoryUtils.closeSession(session);
                if (oldSession != null) {
                    sessionHolder.addSession(oldSession);
                } else {
                    TransactionSynchronizationManager.unbindResource(getSessionFactory());
                }
            }
        }
    }

}