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