public T executeWithNewSession()

in grails-datastore-gorm-hibernate/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java [124:201]


    public <T> T executeWithNewSession(final Closure<T> callable) {
        SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
        SessionHolder previousHolder = sessionHolder;
        ConnectionHolder previousConnectionHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(dataSource);
        Session newSession = null;
        boolean previousActiveSynchronization = TransactionSynchronizationManager.isSynchronizationActive();
        List<TransactionSynchronization> transactionSynchronizations = previousActiveSynchronization ? TransactionSynchronizationManager.getSynchronizations() : null;
        try {
            // if there are any previous synchronizations active we need to clear them and restore them later (see finally block)
            if(previousActiveSynchronization) {
                TransactionSynchronizationManager.clearSynchronization();
                // init a new synchronization to ensure that any opened database connections are closed by the synchronization
                TransactionSynchronizationManager.initSynchronization();
            }

            // if there are already bound holders, unbind them so they can be restored later
            if (sessionHolder != null) {
                TransactionSynchronizationManager.unbindResource(sessionFactory);
                if(previousConnectionHolder != null) {
                    TransactionSynchronizationManager.unbindResource(dataSource);
                }
            }

            // create and bind a new session holder for the new session
            newSession = sessionFactory.openSession();
            applyFlushMode(newSession, false);
            sessionHolder = new SessionHolder(newSession);
            TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);

            return execute(callable::call);
        }
        finally {
            try {
                // if an active synchronization was registered during the life time of the new session clear it
                if(TransactionSynchronizationManager.isSynchronizationActive()) {
                    TransactionSynchronizationManager.clearSynchronization();
                }
                // If there is a synchronization active then leave it to the synchronization to close the session
                if(newSession != null) {
                    SessionFactoryUtils.closeSession(newSession);
                }

                // Clear any bound sessions and connections
                TransactionSynchronizationManager.unbindResource(sessionFactory);
                ConnectionHolder connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResourceIfPossible(dataSource);
                // if there is a connection holder and it holds an open connection close it
                try {
                    if(connectionHolder != null && !connectionHolder.getConnection().isClosed()) {
                        Connection conn = connectionHolder.getConnection();
                        DataSourceUtils.releaseConnection(conn, dataSource);
                    }
                } catch (SQLException e) {
                    // ignore, connection closed already?
                    if(LOG.isDebugEnabled()) {
                        LOG.debug("Could not close opened JDBC connection. Did the application close the connection manually?: " + e.getMessage());
                    }
                }
            }
            finally {
                // if there were previously active synchronizations then register those again
                if(previousActiveSynchronization) {
                    TransactionSynchronizationManager.initSynchronization();
                    for (TransactionSynchronization transactionSynchronization : transactionSynchronizations) {
                        TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
                    }
                }

                // now restore any previous state
                if(previousHolder != null) {
                    TransactionSynchronizationManager.bindResource(sessionFactory, previousHolder);
                    if(previousConnectionHolder != null) {
                        TransactionSynchronizationManager.bindResource(dataSource, previousConnectionHolder);
                    }
                }

            }
        }
    }