with multiple jdbcurl driverclassname datasourceclassname spring-boot flyway hikaricp

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.