I am trying to learn how to work with multiple Datasources in Spring Boot.
I was able to create MultiRoutingDataSource and loaded with Datasources that were configured in application.properties. Here are some code snippets. Full code is at https://github.com/ivoronline/springboot_db_multitenant_dingleentity_shcemaparamtersfromtable
application.properties
# SCHEMA1
schema1.spring.datasource.jdbc-url = jdbc:oracle:thin:@localhost:1522/orcl
schema1.spring.datasource.username = SCHEMA1
schema1.spring.datasource.password = LETMEIN
SchemaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.ivoronline.springboot_db_multitenant_dingleentity_shcemaparamtersfromtable.schema.repository",
entityManagerFactoryRef = "multiEntityManager",
transactionManagerRef = "multiTransactionManager"
)
public class SchemaConfig {
//PROPERTIES
private final String ENTITY_PACKAGE = "com.ivoronline.springboot_db_multitenant_dingleentity_shcemaparamtersfromtable.schema.entity";
//=========================================================================================================
// SCHEMA 1 DATA SOURCE
//=========================================================================================================
@Primary
@Bean
@ConfigurationProperties("schema1.spring.datasource")
public DataSource schema1DataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
//=========================================================================================================
// MULTI ROUTING DATA SOURCE
//=========================================================================================================
@Bean
public MultiRoutingDataSource multiRoutingDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(1, schema1DataSource());
targetDataSources.put(2, schema2DataSource());
//targetDataSources.put(3, schema3DataSource());
MultiRoutingDataSource multiRoutingDataSource = new MultiRoutingDataSource();
multiRoutingDataSource.setDefaultTargetDataSource(schema1DataSource());
multiRoutingDataSource.setTargetDataSources(targetDataSources);
return multiRoutingDataSource;
}
But instead of hard coding connection details in application.properties I would like to take them from Database. For that purpose I have configured another configuration file, Tenant Entity, TenantRepository that just holds name and password for each Schema. But I don’t how to put those Tenants into MultiRoutingDataSource. If I put @Autowired TenantRepository tenantRepository; inside above SchemaConfig.java I get circular Bean reference and can’t use tenantRepository inside multiRoutingDataSource().
If I try to set new setTargetDataSources() inside Control it still doesn’t work.
MyController
@RestController
public class MyController {
//PROPERTIES
@Autowired PersonRepository personRepository;
@Autowired TenantRepository tenantRepository;
@Autowired @Qualifier("multiRoutingDataSource") MultiRoutingDataSource multiRoutingDataSource;
//=========================================================================================================
// MIX STATEMENTS
//=========================================================================================================
@ResponseBody
@GetMapping("/Set")
public String set() {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(3, dataSource3());
multiRoutingDataSource.setTargetDataSources(targetDataSources);
return "OK";
}
//=========================================================================================================
// DATA SOURCE
//=========================================================================================================
public DataSource dataSource3() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl ("jdbc:oracle:thin:@localhost:1522/orcl");
dataSource.setUsername ("SCHEMA3");
dataSource.setPassword ("LETMEIN");
//dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
return dataSource;
}
}