I have a setup my spring web application where there are two data sources, the main one and the secondary one. These two data sources mostly share all configuration properties apart from username, password and url. As the common property list is growing I want to use the common configuration properties for both data sources and only specify which ones to override for the secondary data source and others. For example, I have setup my main data source bean like this:
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
And in the secondary data source:
@Value("${spring.secondaryDatasource.url}")
private String databaseUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driver;
@Bean
public DataSource secondaryDataSource() {
return DataSourceBuilder
.create()
.url(databaseUrl)
.username(username)
.password(password)
.driverClassName(driver)
.build();
}
I've also setup an example project which is similar to my current setup: https://github.com/Edvinas01/MultipleDatasources
Is it possible to inject the repeating properties such as driver name and others while only specifying the ones to override? Something like this (this doesn't work):
@Bean
@ConfigurationProperties(prefix = "spring.datasource") // Inject default properties
public DataSource secondaryDataSource() {
return DataSourceBuilder
.create()
.url(databaseUrl) // Override url
.username(username) // Override username
.password(password) // Override password
.build();
}
Edit:
I've replaced my .properties file to .yml configuration file like so:
spring:
jpa.hibernate.ddl-auto: update
datasource:
username: main
password: main
url: jdbc:hsqldb:mem:main
driver-class-name: org.hsqldb.jdbc.JDBCDriver
---
spring:
profiles: secondary
datasource:
username: secondary
password: secondary
url: jdbc:hsqldb:mem:secondary
---
spring:
profiles.active: default,secondary
And the data source beans:
@Bean
@Primary
@Profile("default")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Profile({"secondary", "default"})
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
My main data source (default) gets the secondary data sources values except for the driver which is not specified in the secondary profile config. While the secondary data source gets the correct properties.
Is there a possible solution for this with without using .yml format for configurations or without having to create multiple .applications files for each profile?
Edit2: Some clarification, on our setup we have current properties files:
application.properties (sets the active profile according to the machine and common properties)
application-stating.properties (staging machine)
application-production.properties (production machine)
Both staging and production environments must use both data sources, so staging has two data sources (main, secondary) and production has two data sources (main, secondary). Settings such as drivers, and few others are shared between main and the secondary data source. The issue comes when trying to inject those common properties into the second data source.