in grails-datastore-gorm-hibernate/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java [280:324]
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSession) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Session session = getSession();
boolean existingTransaction = isSessionTransactional(session);
if (existingTransaction) {
LOG.debug("Found thread-bound Session for HibernateTemplate");
}
FlushMode previousFlushMode = null;
try {
previousFlushMode = applyFlushMode(session, existingTransaction);
if (shouldPassReadOnlyToHibernate()) {
session.setDefaultReadOnly(true);
}
Session sessionToExpose = (enforceNativeSession || exposeNativeSession ? session : createSessionProxy(session));
T result = action.doInHibernate(sessionToExpose);
flushIfNecessary(session, existingTransaction);
return result;
} catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (PersistenceException ex) {
if (ex.getCause() instanceof HibernateException) {
throw SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause());
}
throw ex;
}
catch (SQLException ex) {
throw jdbcExceptionTranslator.translate("Hibernate-related JDBC operation", null, ex);
} catch (RuntimeException ex) {
// Callback code threw application exception...
throw ex;
} finally {
if (existingTransaction) {
LOG.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
if (previousFlushMode != null) {
session.setHibernateFlushMode(previousFlushMode);
}
} else {
SessionFactoryUtils.closeSession(session);
}
}
}