I am using Spring Cloud Task + Batch
in a project.
I plan to use different datasources for business data and Spring audit data on the task. So I configured something like:
@Bean
public TaskConfigurer taskConfigurer() {
return new DefaultTaskConfigurer(this.singletonNotExposedSpringDatasource());
}
@Bean
public BatchConfigurer batchConfigurer() {
return new DefaultBatchConfigurer(this.singletonNotExposedSpringDatasource());
}
whereas main datasource is autoconfigured through JpaBaseConfiguration
.
The problem comes when SimpleBatchConfiguration
+DefaultBatchConfigurer
expose a PlatformTransactionManager
bean, since JpaBaseConfiguration
has a @ConditionalOnMissingBean
on PlatformTransactionManager
. Therefore Batch's PlatformTransactionManager
, binded to the spring.datasource
takes place.
So far, this seems to be caused because this bug
So I tried to emulate what JpaBaseConfiguration
does, defining my own PlatformTransactionManager
over my biz datasource/entityManager.
@Primary
@Bean
public PlatformTransactionManager appTransactionManager(final LocalContainerEntityManagerFactoryBean appEntityManager) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(appEntityManager.getObject());
this.appTransactionManager = transactionManager;
return transactionManager;
}
Note I have to define it with a name other than transactionManager
, otherwise Spring
finds 2 beans and complains (unregardless of @Primary!
)
But now it comes the funny part. When running the tests, everything runs smooth, tests finish and DDLs
are properly created for both business and Batch/Task's
databases, database reads work flawlessly, but business data is not persisted in my testing database, so final assertThats
fail when counting. If I @Autowire
in my test PlatformTransactionManager
or ÈntityManager
, everything indicates they are the proper ones. But if I debug within entityRepository.save
, and execute org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus()
, it seems the DatasourceTransactionManager
from Batch's
configuration is overriding, so my custom exposed PlatformTransactionManager
is not being used.
So I guess it is not a problem of my PlatformManager being the primary, but that something is configuring my JPA layer TransactionInterceptor
to use the non primary but transactionManager
named bean of Batch.
I also tried with making my @Configuration
implement TransactionManagementConfigurer and override PlatformTransactionManager annotationDrivenTransactionManager()
but still no luck
Thus, I guess what I am asking is whether there is a way to configure the primary TransactionManager for the JPA Layer.