Search code examples
javaspringhibernatejpatransactions

Spring Hibernate before Commit Listener


I'm looking for a way to execute a stored procedure before the end of each hibernate transaction.

I don't think the @PostPersit Annotation helps here, as it is bound to one entity and not the whole transaction.

I could add a method call, at the end of each @Transactional method, but that solution is not really satisfying.

Any Ideas ? Thank you !


Solution

  • Depending on what you want, you have two options that I know.

    If you want to perform an action before every transaction committed by Hibernate, you can use an Interceptor (javadoc).

    public class BeforeTransactionCompletionInterceptor extends EmptyInterceptor {
    
        @Override
        public void beforeTransactionCompletion(Transaction tx) {
            // do something before commit
        }
    
    }
    

    With this, the code is run before every commit on Hibernate's level. Which means that even transaction not managed through Spring will call your stored procedure.

    On the other hand, if you want to call your stored procedure before every commit managed by Spring and the @Transactional annotation, you could try with Spring AOP.

    @Aspect
    @Component
    public class CallStoredProcedureBeforeCommitAspect implements Ordered {
    
        @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
        public void transactionnalMethod() {}
    
        @After("transactionnalMethod()")
        public void callStoredProcedureAfter(JoinPoint joinPoint) {
            // do something after
        }
    
        @Override
        public int getOrder() {
            return a_higher_priority;
        }
    }
    

    With AOP don't forget to change the default order of execution of advices, by setting @EnableTransactionManagement(order = a_lower_priority), or the equivalent in XML. Otherwise, the stored procedure will be call after, and not before.