Affects: 5.3.10


It looks like HibernateTransactionManager does not support when an underlying DataSource is annotated with @RefreshScope and then refreshed, when the transaction is in progress.

Having following configuration:

    @Bean
    @RefreshScope
    @ConfigurationProperties("app.jdbc")
    public HikariDataSource theDataSource() {
        return new HikariDataSource();
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource ds) {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(ds);
        localSessionFactoryBean.setPackagesToScan(...);
        return localSessionFactoryBean;
    }

    @Bean
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        return new HibernateTransactionManager(sessionFactory);
    }

when the refresh is triggered and a transaction is currently running, this transaction fails with an exception:

java.lang.IllegalStateException: No value for key [HikariDataSource (null)] bound to thread
    at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:198) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.orm.hibernate5.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:717) ~[spring-orm-5.3.10.jar:5.3.10]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:992) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:790) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.10.jar:5.3.10]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.10.jar:5.3.10]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.10.jar:5.3.10]

Everything works correctly, when I trigger the refresh when no transaction is currently open, further transactions properly use new, reconfigured datasource created by @RefreshScope functionality. Am I missing something in HibernateTransactionManager configuration?

Expected behavior would be to finish the transaction using DataSource present at that time and for all new transactions that start afterwards, use refreshed DataSource. It seems to be the case, except that HibernateTransactionManager does some cleanup that causes the exception and the transaction to fail.

Already tried Hikari and c3p0, this produces the same behavior.

Comment From: snicoll

Refresh scope is a feature that's built on top of the core framework so you'd have to redirect your question to the spring cloud team.