I am trying to configure 2 Datasource in my spring boot batch application.
I want my batch meta-data to persist in my primary marked Datasource configuration.
The batch starts and runs normally. But when I try to save any data in my write step using Primary datasource's repository I get the following below error :
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@1088b120] for key [HikariDataSource (HikariPool-1)] bound to thread [main]
I not able to figure out the issue here. I am providing my 2 Data source configuration classes.
My Primary Datasource configuration :
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "destinationEntityManagerFactory", transactionManagerRef = "destinationTransactionManager",basePackages = {"com.mppkvvcl.batchpoc.repository"})
@ComponentScan(basePackages = {"com.mppkvvcl.batchpoc"})
public class DestinationDatasource {
private static final Logger logger = LoggerFactory.getLogger(DestinationDatasource.class);
@Bean(name = "destinationDataSource")
@Primary
@ConfigurationProperties(prefix = "destination.datasource")
public DataSource destinationDataSource() {
String methodName = "dataSource() : ";
logger.info(methodName + "called");
logger.info(methodName + "returning destination datasource");
return DataSourceBuilder.create().build();
}
@Bean(name = "destinationEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean destinationEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("destinationDataSource") DataSource dataSource) {
String methodName = "destinationEntityManagerFactory() : ";
logger.info(methodName + "called");
return builder.dataSource(dataSource).packages("com.mppkvvcl.batchpoc").persistenceUnit("destination").build();
}
@Bean(name = "destinationTransactionManager")
public PlatformTransactionManager destinationTransactionManager(@Qualifier("destinationEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
String methodName = "destinationTransactionManager() : ";
logger.info(methodName + "called");
return new JpaTransactionManager(entityManagerFactory);
}
}
My Secondary Datasource configuration :
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "sourceEntityManagerFactory", transactionManagerRef = "sourceTransactionManager", basePackages = {"com.mppkvvcl.ngbdao.repositories"})
@ComponentScan(basePackages = {"com.mppkvvcl.ngbdao.daos"})
public class SourceDatasource {
private static final Logger logger = LoggerFactory.getLogger(SourceDatasource.class);
@Bean(name = "sourceDataSource")
@ConfigurationProperties(prefix = "source.datasource")
public DataSource sourceDataSource() {
String methodName = "dataSource() : ";
logger.info(methodName + "called");
logger.info(methodName + "returning source datasource ");
return DataSourceBuilder.create().build();
}
@Bean(name = "sourceEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean sourceEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("sourceDataSource") DataSource dataSource) {
final String methodName = "sourceEntityManagerFactory() : ";
logger.info(methodName + "called");
return builder.dataSource(dataSource).packages("com.mppkvvcl.ngbentity.beans").persistenceUnit("source").build();
}
@Bean(name = "sourceTransactionManager")
public PlatformTransactionManager sourceTransactionManager(@Qualifier("sourceEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
final String methodName = "sourceTransactionManager() : ";
logger.info(methodName + "called");
return new JpaTransactionManager(entityManagerFactory);
}
}
The Exception arises only when I try to use Primary's repository for saving any data through my Primary datasource.
I am unable to debug this issue. Kindly point out the errors or wrong configurations if any.