Example usage for org.springframework.transaction.support TransactionSynchronizationManager registerSynchronization

List of usage examples for org.springframework.transaction.support TransactionSynchronizationManager registerSynchronization

Introduction

In this page you can find the example usage for org.springframework.transaction.support TransactionSynchronizationManager registerSynchronization.

Prototype

public static void registerSynchronization(TransactionSynchronization synchronization)
        throws IllegalStateException 

Source Link

Document

Register a new transaction synchronization for the current thread.

Usage

From source file:org.springframework.datastore.mapping.core.DatastoreUtils.java

/**
 * Get a Datastore Session for the given Datastore. Is aware of and will
 * return any existing corresponding Session bound to the current thread, for
 * example when using {@link org.springframework.datastore.mapping.transactions.DatastoreTransactionManager}. Will create a new
 * Session otherwise, if "allowCreate" is <code>true</code>.
 *
 * @param datastore Datastore to create the session with
 * Session on transaction synchronization (may be <code>null</code>)
 * @param allowCreate whether a non-transactional Session should be created
 * when no transactional Session can be found for the current thread
 * @return the Datastore Session/* ww w . j  a va  2s  . c o  m*/
 * @throws IllegalStateException if no thread-bound Session found and
 * "allowCreate" is <code>false</code>
 */
private static Session doGetSession(Datastore datastore, boolean allowCreate) {

    Assert.notNull(datastore, "No Datastore specified");

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

    if (sessionHolder != null && !sessionHolder.isEmpty()) {
        // pre-bound Datastore Session
        Session session;
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && sessionHolder.doesNotHoldNonDefaultSession()) {
            // Spring transaction management is active ->
            // register pre-bound Session with it for transactional flushing.
            session = sessionHolder.getSession();
            if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
                logger.debug("Registering Spring transaction synchronization for existing Datastore Session");
                TransactionSynchronizationManager.registerSynchronization(
                        new SpringSessionSynchronization(sessionHolder, datastore, false));
                sessionHolder.setSynchronizedWithTransaction(true);

            }
            if (session != null) {
                return session;
            }
        }
    }

    logger.debug("Opening Datastore Session");
    Session session = datastore.connect();

    // Use same Session for further Datastore actions within the transaction.
    // Thread object will get removed by synchronization at transaction completion.
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        // We're within a Spring-managed transaction, possibly from JtaTransactionManager.
        logger.debug("Registering Spring transaction synchronization for new Datastore Session");
        SessionHolder holderToUse = sessionHolder;
        if (holderToUse == null) {
            holderToUse = new SessionHolder(session);
        } else {
            holderToUse.addSession(session);
        }
        TransactionSynchronizationManager
                .registerSynchronization(new SpringSessionSynchronization(holderToUse, datastore, true));
        holderToUse.setSynchronizedWithTransaction(true);
        if (holderToUse != sessionHolder) {
            TransactionSynchronizationManager.bindResource(datastore, holderToUse);
        }
    }

    // Check whether we are allowed to return the Session.
    if (!allowCreate && !isSessionTransactional(session, datastore)) {
        closeSession(session);
        throw new IllegalStateException("No Datastore Session bound to thread, "
                + "and configuration does not allow creation of non-transactional one here");
    }

    return session;
}

From source file:org.springframework.integration.sqs.SQSInboundGateway.java

private void postReceive(final String queueName, final com.amazonaws.queue.doc._2009_02_01.Message message) {
    if (!transaction) {
        template.commitReceive(queueName, message);
    } else {/*from  www. j  a va2  s .  c om*/
        final String receiptHandle = message.getReceiptHandle();
        // add commit/delete message to transaction callback
        TransactionSynchronization value = new TransactionSynchronizationAdapter() {
            @Override
            public void beforeCommit(final boolean readOnly) {
                if (readOnly) {
                    log.warn("Skipping commit receive in read only transaction.");
                } else {
                    template.commitReceive(getQueueName(), receiptHandle);
                }
            }
        };
        TransactionSynchronizationManager.registerSynchronization(value);
    }
}

From source file:org.springframework.jca.cci.connection.ConnectionFactoryUtils.java

/**
 * Actually obtain a CCI Connection from the given ConnectionFactory.
 * Same as {@link #getConnection}, but throwing the original ResourceException.
 * <p>Is aware of a corresponding Connection bound to the current thread, for example
 * when using {@link CciLocalTransactionManager}. Will bind a Connection to the thread
 * if transaction synchronization is active (e.g. if in a JTA transaction).
 * <p>Directly accessed by {@link TransactionAwareConnectionFactoryProxy}.
 * @param cf the ConnectionFactory to obtain Connection from
 * @return a CCI Connection from the given ConnectionFactory
 * @throws ResourceException if thrown by CCI API methods
 * @see #doReleaseConnection//w w  w . ja v  a2 s .  co m
 */
public static Connection doGetConnection(ConnectionFactory cf) throws ResourceException {
    Assert.notNull(cf, "No ConnectionFactory specified");

    ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf);
    if (conHolder != null) {
        return conHolder.getConnection();
    }

    logger.debug("Opening CCI Connection");
    Connection con = cf.getConnection();

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        logger.debug("Registering transaction synchronization for CCI Connection");
        conHolder = new ConnectionHolder(con);
        conHolder.setSynchronizedWithTransaction(true);
        TransactionSynchronizationManager.registerSynchronization(new ConnectionSynchronization(conHolder, cf));
        TransactionSynchronizationManager.bindResource(cf, conHolder);
    }

    return con;
}

From source file:org.springframework.jdbc.datasource.DataSourceUtils.java

/**
 * Actually obtain a JDBC Connection from the given DataSource.
 * Same as {@link #getConnection}, but throwing the original SQLException.
 * <p>Is aware of a corresponding Connection bound to the current thread, for example
 * when using {@link DataSourceTransactionManager}. Will bind a Connection to the thread
 * if transaction synchronization is active (e.g. if in a JTA transaction).
 * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
 * @param dataSource the DataSource to obtain Connections from
 * @return a JDBC Connection from the given DataSource
 * @throws SQLException if thrown by JDBC methods
 * @see #doReleaseConnection//from   w ww.j  av a 2 s . co m
 */
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
    Assert.notNull(dataSource, "No DataSource specified");

    ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
    if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
        conHolder.requested();
        if (!conHolder.hasConnection()) {
            logger.debug("Fetching resumed JDBC Connection from DataSource");
            conHolder.setConnection(fetchConnection(dataSource));
        }
        return conHolder.getConnection();
    }
    // Else we either got no holder or an empty thread-bound holder here.

    logger.debug("Fetching JDBC Connection from DataSource");
    Connection con = fetchConnection(dataSource);

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        logger.debug("Registering transaction synchronization for JDBC Connection");
        // Use same Connection for further JDBC actions within the transaction.
        // Thread-bound object will get removed by synchronization at transaction completion.
        ConnectionHolder holderToUse = conHolder;
        if (holderToUse == null) {
            holderToUse = new ConnectionHolder(con);
        } else {
            holderToUse.setConnection(con);
        }
        holderToUse.requested();
        TransactionSynchronizationManager
                .registerSynchronization(new ConnectionSynchronization(holderToUse, dataSource));
        holderToUse.setSynchronizedWithTransaction(true);
        if (holderToUse != conHolder) {
            TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
        }
    }

    return con;
}

From source file:org.springframework.jdbc.support.lob.LobCreatorUtils.java

/**
 * Register a transaction synchronization for closing the given LobCreator,
 * preferring Spring transaction synchronization and falling back to
 * plain JTA transaction synchronization.
 * @param lobCreator the LobCreator to close after transaction completion
 * @param jtaTransactionManager the JTA TransactionManager to fall back to
 * when no Spring transaction synchronization is active (may be {@code null})
 * @throws IllegalStateException if there is neither active Spring transaction
 * synchronization nor active JTA transaction synchronization
 *//*ww  w.j av  a 2 s . co m*/
public static void registerTransactionSynchronization(LobCreator lobCreator,
        TransactionManager jtaTransactionManager) throws IllegalStateException {

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        logger.debug("Registering Spring transaction synchronization for LobCreator");
        TransactionSynchronizationManager
                .registerSynchronization(new SpringLobCreatorSynchronization(lobCreator));
    } else {
        if (jtaTransactionManager != null) {
            try {
                int jtaStatus = jtaTransactionManager.getStatus();
                if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
                    logger.debug("Registering JTA transaction synchronization for LobCreator");
                    jtaTransactionManager.getTransaction()
                            .registerSynchronization(new JtaLobCreatorSynchronization(lobCreator));
                    return;
                }
            } catch (Throwable ex) {
                throw new TransactionSystemException(
                        "Could not register synchronization with JTA TransactionManager", ex);
            }
        }
        throw new IllegalStateException("Active Spring transaction synchronization or active "
                + "JTA transaction with specified [javax.transaction.TransactionManager] required");
    }
}

From source file:org.springframework.jms.connection.ConnectionFactoryUtils.java

/**
 * Obtain a JMS Session that is synchronized with the current transaction, if any.
 * @param connectionFactory the JMS ConnectionFactory to bind for
 * (used as TransactionSynchronizationManager key)
 * @param resourceFactory the ResourceFactory to use for extracting or creating
 * JMS resources/*from   www .j  a v a 2 s . c om*/
 * @param startConnection whether the underlying JMS Connection approach should be
 * started in order to allow for receiving messages. Note that a reused Connection
 * may already have been started before, even if this flag is {@code false}.
 * @return the transactional Session, or {@code null} if none found
 * @throws JMSException in case of JMS failure
 */
@Nullable
public static Session doGetTransactionalSession(ConnectionFactory connectionFactory,
        ResourceFactory resourceFactory, boolean startConnection) throws JMSException {

    Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
    Assert.notNull(resourceFactory, "ResourceFactory must not be null");

    JmsResourceHolder resourceHolder = (JmsResourceHolder) TransactionSynchronizationManager
            .getResource(connectionFactory);
    if (resourceHolder != null) {
        Session session = resourceFactory.getSession(resourceHolder);
        if (session != null) {
            if (startConnection) {
                Connection con = resourceFactory.getConnection(resourceHolder);
                if (con != null) {
                    con.start();
                }
            }
            return session;
        }
        if (resourceHolder.isFrozen()) {
            return null;
        }
    }
    if (!TransactionSynchronizationManager.isSynchronizationActive()) {
        return null;
    }
    JmsResourceHolder resourceHolderToUse = resourceHolder;
    if (resourceHolderToUse == null) {
        resourceHolderToUse = new JmsResourceHolder(connectionFactory);
    }
    Connection con = resourceFactory.getConnection(resourceHolderToUse);
    Session session = null;
    try {
        boolean isExistingCon = (con != null);
        if (!isExistingCon) {
            con = resourceFactory.createConnection();
            resourceHolderToUse.addConnection(con);
        }
        session = resourceFactory.createSession(con);
        resourceHolderToUse.addSession(session, con);
        if (startConnection) {
            con.start();
        }
    } catch (JMSException ex) {
        if (session != null) {
            try {
                session.close();
            } catch (Throwable ex2) {
                // ignore
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (Throwable ex2) {
                // ignore
            }
        }
        throw ex;
    }
    if (resourceHolderToUse != resourceHolder) {
        TransactionSynchronizationManager.registerSynchronization(new JmsResourceSynchronization(
                resourceHolderToUse, connectionFactory, resourceFactory.isSynchedLocalTransactionAllowed()));
        resourceHolderToUse.setSynchronizedWithTransaction(true);
        TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
    }
    return session;
}

From source file:org.springframework.orm.hibernate.SessionFactoryUtils.java

/**
 * Get a Hibernate Session for the given SessionFactory. Is aware of and will
 * return any existing corresponding Session bound to the current thread, for
 * example when using {@link HibernateTransactionManager}. Will create a new
 * Session otherwise, if "allowCreate" is <code>true</code>.
 * @param sessionFactory Hibernate SessionFactory to create the session with
 * @param entityInterceptor Hibernate entity interceptor, or <code>null</code> if none
 * @param jdbcExceptionTranslator SQLExceptionTranslator to use for flushing the
 * Session on transaction synchronization (may be <code>null</code>)
 * @param allowCreate whether a non-transactional Session should be created
 * when no transactional Session can be found for the current thread
 * @return the Hibernate Session/*from  w  w w  . ja va2 s  .co m*/
 * @throws DataAccessResourceFailureException if the Session couldn't be created
 * @throws IllegalStateException if no thread-bound Session found and
 * "allowCreate" is <code>false</code>
 */
private static Session getSession(SessionFactory sessionFactory, Interceptor entityInterceptor,
        SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
        throws DataAccessResourceFailureException, IllegalStateException {

    Assert.notNull(sessionFactory, "No SessionFactory specified");

    SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
    if (sessionHolder != null && !sessionHolder.isEmpty()) {
        // pre-bound Hibernate Session
        Session session = null;
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && sessionHolder.doesNotHoldNonDefaultSession()) {
            // Spring transaction management is active ->
            // register pre-bound Session with it for transactional flushing.
            session = sessionHolder.getValidatedSession();
            if (!sessionHolder.isSynchronizedWithTransaction()) {
                logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
                TransactionSynchronizationManager.registerSynchronization(new SpringSessionSynchronization(
                        sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
                sessionHolder.setSynchronizedWithTransaction(true);
                // Switch to FlushMode.AUTO if we're not within a read-only transaction.
                FlushMode flushMode = session.getFlushMode();
                if (FlushMode.NEVER.equals(flushMode)
                        && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                    session.setFlushMode(FlushMode.AUTO);
                    sessionHolder.setPreviousFlushMode(flushMode);
                }
            }
        } else {
            // No Spring transaction management active -> try JTA transaction synchronization.
            session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
        }
        if (session != null) {
            return session;
        }
    }

    try {
        logger.debug("Opening Hibernate Session");
        Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor)
                : sessionFactory.openSession());

        // Set Session to FlushMode.NEVER if we're within a read-only transaction.
        // Use same Session for further Hibernate actions within the transaction.
        // Thread object will get removed by synchronization at transaction completion.
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            // We're within a Spring-managed transaction, possibly from JtaTransactionManager.
            logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
            SessionHolder holderToUse = sessionHolder;
            if (holderToUse == null) {
                holderToUse = new SessionHolder(session);
            } else {
                holderToUse.addSession(session);
            }
            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                session.setFlushMode(FlushMode.NEVER);
            }
            TransactionSynchronizationManager.registerSynchronization(new SpringSessionSynchronization(
                    holderToUse, sessionFactory, jdbcExceptionTranslator, true));
            holderToUse.setSynchronizedWithTransaction(true);
            if (holderToUse != sessionHolder) {
                TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
            }
        } else {
            // No Spring transaction management active -> try JTA transaction synchronization.
            registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
        }

        // Check whether we are allowed to return the Session.
        if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
            doClose(session);
            throw new IllegalStateException("No Hibernate Session bound to thread, "
                    + "and configuration does not allow creation of non-transactional one here");
        }

        return session;
    } catch (HibernateException ex) {
        throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
    }
}

From source file:org.springframework.orm.hibernate.support.AbstractLobType.java

/**
 * This implementation delegates to nullSafeSetInternal,
 * passing in a transaction-synchronized LobCreator for the
 * LobHandler of this type.//from   ww  w.j a va 2  s.c o m
 * @see #nullSafeSetInternal
 */
public final void nullSafeSet(PreparedStatement st, Object value, int index)
        throws HibernateException, SQLException {

    if (this.lobHandler == null) {
        throw new IllegalStateException("No LobHandler found for configuration - "
                + "lobHandler property must be set on LocalSessionFactoryBean");
    }

    LobCreator lobCreator = this.lobHandler.getLobCreator();
    try {
        nullSafeSetInternal(st, index, value, lobCreator);
    } catch (IOException ex) {
        throw new HibernateException("I/O errors during LOB access", ex);
    }
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        logger.debug("Registering Spring transaction synchronization for Hibernate LOB type");
        TransactionSynchronizationManager
                .registerSynchronization(new SpringLobCreatorSynchronization(lobCreator));
    } else {
        if (this.jtaTransactionManager != null) {
            try {
                int jtaStatus = this.jtaTransactionManager.getStatus();
                if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
                    logger.debug("Registering JTA transaction synchronization for Hibernate LOB type");
                    this.jtaTransactionManager.getTransaction()
                            .registerSynchronization(new JtaLobCreatorSynchronization(lobCreator));
                    return;
                }
            } catch (Exception ex) {
                throw new DataAccessResourceFailureException(
                        "Could not register synchronization with JTA TransactionManager", ex);
            }
        }
        throw new IllegalStateException("Active Spring transaction synchronization or active "
                + "JTA transaction with 'jtaTransactionManager' on LocalSessionFactoryBean required");
    }
}

From source file:org.springframework.orm.hibernate3.SessionFactoryUtils.java

/**
 * Get a Hibernate Session for the given SessionFactory. Is aware of and will
 * return any existing corresponding Session bound to the current thread, for
 * example when using {@link HibernateTransactionManager}. Will create a new
 * Session otherwise, if "allowCreate" is {@code true}.
 * <p>Same as {@link #getSession}, but throwing the original HibernateException.
 * @param sessionFactory Hibernate SessionFactory to create the session with
 * @param entityInterceptor Hibernate entity interceptor, or {@code null} if none
 * @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the
 * Session on transaction synchronization (may be {@code null})
 * @param allowCreate whether a non-transactional Session should be created
 * when no transactional Session can be found for the current thread
 * @return the Hibernate Session// w  w w.  j  av a 2s.  com
 * @throws HibernateException if the Session couldn't be created
 * @throws IllegalStateException if no thread-bound Session found and
 * "allowCreate" is {@code false}
 */
private static Session doGetSession(SessionFactory sessionFactory, Interceptor entityInterceptor,
        SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
        throws HibernateException, IllegalStateException {

    Assert.notNull(sessionFactory, "No SessionFactory specified");

    Object resource = TransactionSynchronizationManager.getResource(sessionFactory);
    if (resource instanceof Session) {
        return (Session) resource;
    }
    SessionHolder sessionHolder = (SessionHolder) resource;
    if (sessionHolder != null && !sessionHolder.isEmpty()) {
        // pre-bound Hibernate Session
        Session session = null;
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && sessionHolder.doesNotHoldNonDefaultSession()) {
            // Spring transaction management is active ->
            // register pre-bound Session with it for transactional flushing.
            session = sessionHolder.getValidatedSession();
            if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
                logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
                TransactionSynchronizationManager.registerSynchronization(new SpringSessionSynchronization(
                        sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
                sessionHolder.setSynchronizedWithTransaction(true);
                // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
                // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
                FlushMode flushMode = session.getFlushMode();
                if (flushMode.lessThan(FlushMode.COMMIT)
                        && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                    session.setFlushMode(FlushMode.AUTO);
                    sessionHolder.setPreviousFlushMode(flushMode);
                }
            }
        } else {
            // No Spring transaction management active -> try JTA transaction synchronization.
            session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
        }
        if (session != null) {
            return session;
        }
    }

    logger.debug("Opening Hibernate Session");
    Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor)
            : sessionFactory.openSession());

    // Use same Session for further Hibernate actions within the transaction.
    // Thread object will get removed by synchronization at transaction completion.
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        // We're within a Spring-managed transaction, possibly from JtaTransactionManager.
        logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
        SessionHolder holderToUse = sessionHolder;
        if (holderToUse == null) {
            holderToUse = new SessionHolder(session);
        } else {
            holderToUse.addSession(session);
        }
        if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
            session.setFlushMode(FlushMode.MANUAL);
        }
        TransactionSynchronizationManager.registerSynchronization(
                new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));
        holderToUse.setSynchronizedWithTransaction(true);
        if (holderToUse != sessionHolder) {
            TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
        }
    } else {
        // No Spring transaction management active -> try JTA transaction synchronization.
        registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
    }

    // Check whether we are allowed to return the Session.
    if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
        closeSession(session);
        throw new IllegalStateException("No Hibernate Session bound to thread, "
                + "and configuration does not allow creation of non-transactional one here");
    }

    return session;
}

From source file:org.springframework.orm.hibernate4.SpringSessionContext.java

/**
 * Retrieve the Spring-managed Session for the current thread, if any.
 *//*from   ww  w  . ja  va 2  s.co  m*/
@Override
public Session currentSession() throws HibernateException {
    Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
    if (value instanceof Session) {
        return (Session) value;
    } else if (value instanceof SessionHolder) {
        SessionHolder sessionHolder = (SessionHolder) value;
        Session session = sessionHolder.getSession();
        if (!sessionHolder.isSynchronizedWithTransaction()
                && TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(
                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
            sessionHolder.setSynchronizedWithTransaction(true);
            // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
            // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
            FlushMode flushMode = session.getFlushMode();
            if (flushMode.equals(FlushMode.MANUAL)
                    && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                session.setFlushMode(FlushMode.AUTO);
                sessionHolder.setPreviousFlushMode(flushMode);
            }
        }
        return session;
    }

    if (this.transactionManager != null) {
        try {
            if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
                Session session = this.jtaSessionContext.currentSession();
                if (TransactionSynchronizationManager.isSynchronizationActive()) {
                    TransactionSynchronizationManager
                            .registerSynchronization(new SpringFlushSynchronization(session));
                }
                return session;
            }
        } catch (SystemException ex) {
            throw new HibernateException("JTA TransactionManager found but status check failed", ex);
        }
    }

    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        Session session = this.sessionFactory.openSession();
        if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
            session.setFlushMode(FlushMode.MANUAL);
        }
        SessionHolder sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.registerSynchronization(
                new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
        TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
        sessionHolder.setSynchronizedWithTransaction(true);
        return session;
    } else {
        throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
    }
}