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.