We have an spring boot application with multiple datasources, configured in properties with different namespaces as:
spring.datasource.DB1.url=jdbc:postgresql://localhost:5432/postgres1
spring.datasource.DB1.username=DB1_USER
spring.datasource.DB1.password=DB2_PASSWORD
spring.datasource.DB1.driver-class-name = org.postgresql.Driver
spring.datasource.DB2.url=jdbc:postgresql://localhost:5432/postgres2
spring.datasource.DB2.username=DB1_USER
spring.datasource.DB2.password=DB2_PASSWORD
spring.datasource.DB2.driver-class-name = org.postgresql.Driver
And in the @Configuration class this databases are initialized as
@Primary
@Bean("DB1")
@ConfigurationProperties(prefix = "spring.datasource.DB1")
public DataSource pricingDatasource() {
return DataSourceBuilder.create().build();
}
@Bean("DB2")
@ConfigurationProperties(prefix = "spring.datasource.DB2")
public DataSource pricingDatasource() {
return DataSourceBuilder.create().build();
}
md5-536ab3b124886d7f0a07682325a7dd61
Caused by: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:1059) ~[classes/:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109) ~[classes/:na]
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:385) ~[liquibase-core-3.5.5.jar:na]
md5-9f8ea6feabcb75ee2579fa54f6b8aa7d
Caused by: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:1063) ~[classes/:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109) ~[classes/:na]
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:385) ~[liquibase-core-3.5.5.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 16 common frames omitted
md5-dc2a2dd9e397bc0df0277df3303eb511
spring.datasource.DB1.url=jdbc:postgresql://localhost:5432/postgres1
spring.datasource.DB1.jdbcUrl=${spring.datasource.DB1.url}
spring.datasource.DB1.username=DB1_USER
spring.datasource.DB1.password=DB2_PASSWORD
spring.datasource.DB1.driver-class-name = org.postgresql.Driver
spring.datasource.DB2.url=jdbc:postgresql://localhost:5432/postgres2
spring.datasource.DB2.jdbcUrl=${spring.datasource.DB2.url}
spring.datasource.DB2.username=DB1_USER
spring.datasource.DB2.password=DB2_PASSWORD
spring.datasource.DB2.driver-class-name = org.postgresql.Driver
That's not how you should configure custom datasources if you want to simulate what the auto-configuration does. There is a dedicated section in the documentation that shows you how to accomplish this.
DataSourceBuilder
can't replace jdbcUrl
to url
in your code snippet as the binding is done externally (via @ConfigurationProperties
)
If you use the technique explained in the documentation, you could also omit the jdbc driver as it is automatically detected.
Many thanks for the clarification. One question en relation with the documentation referenced.
If the datasource can be initialized with a DataSourceProperties bean previously initialized with the @ConfigurationProperties.
Why is it necessary to include the same @ConfigurationProperties in the datasource bean?
BR
Hi,
Were you able to resolve it? I am facing same issue. Can you share the application properties format used for 2 datasources configuration that worked for you? In my case, first datasource is already configured via java code. Now, I need to add another datasource and I am trying to add 2nd datasource in application.properties file. But getting error: org.springframework.boot.context.properties.source.InvalidConfigurationPropertyNameException: Configuration property name 'postgresql.secondDatasource' is not valid.
postgresql.secondDatasource.jdbc-url=jdbc:postgresql://.........
postgresql.secondDatasource.username=XXXXX
postgresql.secondDatasource.password=XXXXX
postgresql.secondDatasource.driverClassName=org.postgresql.Driver
(In my case, both datasources are of postgresql but they are in different servers)
I don't have the exact source code right now...
But I think I did this in configuration class..
@Bean(name = {"dataSourceA"})
@ConfigurationProperties(prefix = "app.datasource.com")
public DataSource comDatasource() {
return DataSourceBuilder.create().build();
}
@Bean(name = {"dataSourceB"})
@ConfigurationProperties(prefix = "app.datasource.fin")
public DataSource finDatasource() {
return DataSourceBuilder.create().build();
}
And then the properties duplicated with the prefix...
app.datasource.com.jdbc-url=jdbc:postgresql://.........
app.datasource.com.username=XXXXX
app.datasource.com.password=XXXXX
app.datasource.com.driverClassName=org.postgresql.Driver
app.datasource.fin.jdbc-url=jdbc:postgresql://.........
app.datasource.fin.username=XXXXX
app.datasource.fin.password=XXXXX
app.datasource.fin.driverClassName=org.postgresql.Driver
So if you need datasource @Autowired you need to add the specific qualifier...
Look out if you plan to used distributed transactions that are not supported by spring by default
(https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/jta/JtaTransactionManager.html).
Most helpful comment
That's not how you should configure custom datasources if you want to simulate what the auto-configuration does. There is a dedicated section in the documentation that shows you how to accomplish this.
DataSourceBuilder
can't replacejdbcUrl
tourl
in your code snippet as the binding is done externally (via@ConfigurationProperties
)If you use the technique explained in the documentation, you could also omit the jdbc driver as it is automatically detected.