Java Spring application that needs to interact with multiple MySQL databases. Each database has the same schema and tables, and the list of these databases can vary dynamically. I am using a custom datasourceconfig to load all the datasources. I then have a requirement to execute a mysql script across all the datasources gathered in the Map and then update a particular table.
;
I am executing the script in such a way
@Transactional
public void executeSqlScript() throws SQLException {
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
ScriptUtils.executeSqlScript(entry.getValue().getConnection(), new ClassPathResource("test.sql"));
}
}
But i also want to get and update a particular table using spring JPA.
TestTable testTable = testTableRepository.findLatest();
The issue i am facing is how to deal with multiple dynamic databases when configuring. Because when running the script method, i dont have any issues. I face errors when accessing the @Respository class. It is complaining about entitymangager.
This is how my datasources are being loaded:
CONFIG::
datasource:
connectionPrefix: jdbc:mysql://localhost:3306/
username: root
password: root
databases:
- demo1
- demo2
- demo3
- demo4
@Bean
public Map<String, DataSource> localDataSources() throws SQLException {
Map<String, DataSource> dataSources = new HashMap<>();
for (String db : dataSourceConfigProperties.getDatabases()) {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser(dataSourceConfigProperties.getUsername());
dataSource.setPassword(dataSourceConfigProperties.getPassword());
dataSource.setUrl(dataSourceConfigProperties.getConnectionPrefix() + db);
dataSources.put(dataSourceConfigProperties.getConnectionPrefix() + db, dataSource);
return dataSources;
}
@Bean
public Map<String, LocalContainerEntityManagerFactoryBean> entityManagerFactories(Map<String, DataSource> dataSources) {
Map<String, LocalContainerEntityManagerFactoryBean> entityManagerFactories = new HashMap<>();
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
LocalContainerEntityManagerFactoryBean emFactoryBean = new LocalContainerEntityManagerFactoryBean();
emFactoryBean.setDataSource(entry.getValue());
emFactoryBean.setPackagesToScan("com.test.mangager.model"); // Set the package to scan for entities
emFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", "update");
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
emFactoryBean.setJpaPropertyMap(properties);
emFactoryBean.afterPropertiesSet();
entityManagerFactories.put(entry.getKey(), emFactoryBean);
}
return entityManagerFactories;
}
@Bean
public Map<String, EntityManager> entityManagers(Map<String, LocalContainerEntityManagerFactoryBean> entityManagerFactories) {
Map<String, EntityManager> entityManagers = new HashMap<>();
for (Map.Entry<String, LocalContainerEntityManagerFactoryBean> entry : entityManagerFactories.entrySet()) {
EntityManager em = entry.getValue().getObject().createEntityManager();
entityManagers.put(entry.getKey(), em);
}
return entityManagers;
}
@Bean
public Map<String, PlatformTransactionManager> transactionManager(Map<String, DataSource> dataSources) {
Map<String, PlatformTransactionManager> transactionManagers = new HashMap<>();
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
transactionManagers.put(entry.getKey(), new DataSourceTransactionManager(entry.getValue()));
}
return transactionManagers;
}
ERROR:
Error creating bean with name ‘testTableRepository’ defined in com.test.manager.repository.TestTableRepositorydefined in @EnableJpaRepositories declared on app: Cannot resolve reference to bean ‘jpaSharedEM_entityManagerFactory’ while setting bean property ‘entityManager’
3