spring-boot - multiple - spring boot 2 datasource or datasourceclassname or jdbcurl is required
Cómo usar HikariCP en Spring Boot con dos fuentes de datos junto con Flyway (2)
¡Gracias Andy por tu respuesta rápida y valiosa! Me pusiste en el camino correcto. Después de juguetear, encontré que esta configuración me funciona:
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
//@ConfigurationProperties("spring.datasource.hikari") can also be used, no difference
public DataSourceProperties mySQLDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari")
public DataSource mySQLDataSource() {
return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
y tuve que agregar estas configuraciones en application.properties:
# this is absolutely mandatory otherwise BeanInstantiationException in mySQLDataSource !
spring.datasource.url=${JDBC_CONNECTION_STRING}
spring.datasource.hikari.jdbc-url=${JDBC_CONNECTION_STRING}
spring.datasource.hikari.username=user
spring.datasource.hikari.password=pass
Quiero usar HikariCP como grupo de conexiones JDBC en mi aplicación de arranque Spring. Tengo dos fuentes de datos (base de datos MySQL como base de datos primaria y acceso a esos datos a través de Hibernate y, además, una base de datos Oracle para leer otros datos a través de JDBCTemplate).
Establecí el origen de datos MySQL como bean primario:
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties mySQLDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource mySQLDataSource() {
return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
@ConfigurationProperties("oracle.datasource")
public DataSourceProperties oracleDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "oracleDatabase")
@ConfigurationProperties("oracle.datasource")
public DataSource oracleDataSource() {
return oracleDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
public JdbcTemplate oracleJdbcTemplate(@Qualifier("oracleDatabase") DataSource oracleDb) {
return new JdbcTemplate(oracleDb);
}
y puse las siguientes configuraciones en mi application.properties:
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=7
spring.datasource.hikari.pool-name=Test-1
spring.datasource.hikari.data-source-properties.prepStmtCacheSize=250
spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=2048
spring.datasource.hikari.data-source-properties.cachePrepStmts=true
spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
Sin pretenderlo, estas configuraciones de HikariCP no se están leyendo:
HikariConfig - dataSourceJNDI..................none
HikariConfig - dataSourceProperties............{password=<masked>}
HikariConfig - driverClassName................."com.mysql.jdbc.Driver"
HikariConfig - healthCheckProperties...........{}
HikariConfig - healthCheckRegistry.............none
HikariConfig - idleTimeout.....................600000
HikariConfig - initializationFailFast..........true
HikariConfig - initializationFailTimeout.......1
HikariConfig - isolateInternalQueries..........false
HikariConfig - jdbc4ConnectionTest.............false
HikariConfig - jdbcUrl........................."jdbc:mysql://localhost:3306/testDB"
HikariConfig - leakDetectionThreshold..........0
HikariConfig - maxLifetime.....................1800000
HikariConfig - maximumPoolSize.................10
HikariConfig - metricRegistry..................none
HikariConfig - metricsTrackerFactory...........none
HikariConfig - minimumIdle.....................10
HikariConfig - password........................<masked>
HikariConfig - poolName........................"HikariPool-1"
Creando los beans HikariCP y desactivando la autoconfiguración de DataSource y eliminando "spring.datasource":
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@SpringBootApplication
@ComponentScan
public class SpringApplication {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
resuelve mi problema:
HikariConfig - dataSourceJNDI..................none
HikariConfig - dataSourceProperties............{password=<masked>, prepStmtCacheSqlLimit=2048, cachePrepStmts=true, useServerPrepStmts=true, prepStmtCacheSize=250}
HikariConfig - driverClassName................."com.mysql.jdbc.Driver"
HikariConfig - healthCheckProperties...........{}
HikariConfig - healthCheckRegistry.............none
HikariConfig - idleTimeout.....................600000
HikariConfig - initializationFailFast..........true
HikariConfig - initializationFailTimeout.......1
HikariConfig - isolateInternalQueries..........false
HikariConfig - jdbc4ConnectionTest.............false
HikariConfig - jdbcUrl........................."jdbc:mysql://localhost:3306/testDB?autoReconnect=true"
HikariConfig - leakDetectionThreshold..........0
HikariConfig - maxLifetime.....................1800000
HikariConfig - poolName........................"Test-1"
Pero entonces, el Flyway muestra algunas advertencias extrañas que no se habían mostrado antes y tengo que crear el esquema de base de datos manualmente antes de ejecutar la aplicación Spring, es decir: el esquema de creación ya no funciona.
[WARN ] JdbcTemplate - DB: Can''t create database ''test''; database exists (SQL State: HY000 - Error Code: 1007)
[WARN ] JdbcTemplate - DB: Unknown table ''testSchema.tenant'' (SQL State: 42S02 - Error Code: 1051)
[WARN ] JdbcTemplate - DB: Unknown table ''testSchema.user'' (SQL State: 42S02 - Error Code: 1051)
Mis scripts Flyway SQL son scripts DDL simples:
CREATE SCHEMA IF NOT EXISTS `testSchema` DEFAULT CHARACTER SET utf8 ;
DROP TABLE IF EXISTS `testSchema`.`tenant`;
CREATE TABLE `testSchema`.`tenant` (
`id` int NOT NULL AUTO_INCREMENT,
Creo que deshabilitar la configuración de origen de datos automático no es la mejor solución ya que Flyway deja de crear el esquema y muestra advertencias. ¿Hay alguna otra forma de resolver esto?
Al declarar su propio DataSource
ya habrá implícitamente deshabilitado la configuración automática de Spring Boot de una fuente de datos. En otras palabras, esto no tendrá ningún efecto:
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
Creo que el problema radica en el hecho de que no está vinculando la configuración específica de Hikari a su MySQL DataSource
. Debes hacer algo como esto:
@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari")
public DataSource mySQLDataSource() {
return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
}
Esto significará que sus mySQLDataSourceProperties
están configuradas con una configuración de fuente de datos de propósito general. Luego crean un HikariDataSource
que además se configura con la configuración específica de Hikari.