Index: lams_common/src/java/org/lamsfoundation/lams/util/TransactionRetryService.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r3ecddf4b3b716fbd0c0767f12f524278b8fe455a --- lams_common/src/java/org/lamsfoundation/lams/util/TransactionRetryService.java (.../TransactionRetryService.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/util/TransactionRetryService.java (.../TransactionRetryService.java) (revision 3ecddf4b3b716fbd0c0767f12f524278b8fe455a) @@ -23,13 +23,23 @@ package org.lamsfoundation.lams.util; import org.aopalliance.intercept.MethodInvocation; +import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; /** * Invokes the given service method with a new transaction. */ public class TransactionRetryService implements ITransactionRetryService { @Override public Object retry(MethodInvocation invocation) throws Throwable { + // LDEV-4915 introduced it + + // This method uses PROPAGATION_REQUIRES_NEW, + // but if first attempt of running the target method failed then we are left without a Hibernate session + // and we need to open it manually. + + // Hopefully this can be rewritten back to automatic session management at some point. + HibernateSessionManager.openSessionIfNecessary(); + return invocation.proceed(); } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/hibernate/HibernateSessionManager.java =================================================================== diff -u -r18a207719c2aa30f683987fd0bb9176521b704de -r3ecddf4b3b716fbd0c0767f12f524278b8fe455a --- lams_common/src/java/org/lamsfoundation/lams/util/hibernate/HibernateSessionManager.java (.../HibernateSessionManager.java) (revision 18a207719c2aa30f683987fd0bb9176521b704de) +++ lams_common/src/java/org/lamsfoundation/lams/util/hibernate/HibernateSessionManager.java (.../HibernateSessionManager.java) (revision 3ecddf4b3b716fbd0c0767f12f524278b8fe455a) @@ -46,6 +46,13 @@ } } + public static void openSessionIfNecessary() { + // this call does not only fetch current session + // if an open session is missing from Context, it creates it and binds it + // with TransactionAwareSessionContext#currentSession() + HibernateSessionManager.getSessionFactory().getCurrentSession(); + } + private static SessionFactory getSessionFactory() { if (HibernateSessionManager.sessionFactory == null) { WebApplicationContext wac = WebApplicationContextUtils Index: lams_common/src/java/org/lamsfoundation/lams/web/filter/TransactionRetryInterceptor.java =================================================================== diff -u -r80befea7836aebb10f448ff3ad8c8f3a4522725a -r3ecddf4b3b716fbd0c0767f12f524278b8fe455a --- lams_common/src/java/org/lamsfoundation/lams/web/filter/TransactionRetryInterceptor.java (.../TransactionRetryInterceptor.java) (revision 80befea7836aebb10f448ff3ad8c8f3a4522725a) +++ lams_common/src/java/org/lamsfoundation/lams/web/filter/TransactionRetryInterceptor.java (.../TransactionRetryInterceptor.java) (revision 3ecddf4b3b716fbd0c0767f12f524278b8fe455a) @@ -34,6 +34,8 @@ import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.transaction.UnexpectedRollbackException; +import org.springframework.transaction.interceptor.TransactionAspectSupport; +import org.springframework.transaction.support.TransactionSynchronizationManager; /** * Retries proxied method in case of an exception. First attempt is processed as usual. Retrying requires a new @@ -58,6 +60,18 @@ if (attempt.intValue() == 1) { return invocation.proceed(); } else { + String transactionName = TransactionSynchronizationManager.getCurrentTransactionName(); + if (transactionName != null && log.isDebugEnabled()) { + log.debug("Transaction context for retry of method " + + invocation.getMethod().getDeclaringClass().getName() + "#" + + invocation.getMethod().getName() + ". Name: " + transactionName + ", active: " + + TransactionSynchronizationManager.isActualTransactionActive() + ", completed: " + + TransactionAspectSupport.currentTransactionStatus().isCompleted() + ", new : " + + TransactionAspectSupport.currentTransactionStatus().isNewTransaction() + + ", rollback: " + + TransactionAspectSupport.currentTransactionStatus().isRollbackOnly()); + } + return transactionRetryService.retry(invocation); } } catch (DataIntegrityViolationException e) {