So, I've configured my spring boot application to handle multiple datasource everything is good, but I noticed that when I launch the application, the primary datasource's pool is started but not the others, only when they are needed (which sometimes results in nullpointer...)
2020-03-05 15:34:02.478 INFO 11172 --- [ main] be.MyApp.ESPI.EspiApplication :
Starting EspiApplication on BESVC-HQ2000928 with PID 11172 (C:\Users\...\Documents\MyApp\Others\ESPI\ESPI\target\classes started by ... in C:\Users\...\Documents\MyApp\Others\ESPI\ESPI)
2020-03-05 15:34:02.483 INFO 11172 --- [ main] be.MyApp.ESPI.EspiApplication : The following profiles are active: dev
2020-03-05 15:34:03.149 INFO 11172 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-03-05 15:34:03.233 INFO 11172 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 65ms. Found 2 JPA repository interfaces.
2020-03-05 15:34:03.811 INFO 11172 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-03-05 15:34:04.433 INFO 11172 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-03-05 15:34:04.444 INFO 11172 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-03-05 15:34:04.444 INFO 11172 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-03-05 15:34:04.603 INFO 11172 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-03-05 15:34:04.603 INFO 11172 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2047 ms
2020-03-05 15:34:04.761 WARN 11172 --- [ main] com.zaxxer.hikari.HikariConfig : FirstPool - maxLifetime is less than 30000ms, setting to default 1800000ms.
2020-03-05 15:34:04.761 INFO 11172 --- [ main] com.zaxxer.hikari.HikariDataSource : FirstPool - Starting...
2020-03-05 15:34:05.095 INFO 11172 --- [ main] com.zaxxer.hikari.pool.PoolBase : FirstPool - Driver does not support get/set network timeout for connections. (oracle.jdbc.driver.T4CConnection.getNetworkTimeout()I)
2020-03-05 15:34:05.099 INFO 11172 --- [ main] com.zaxxer.hikari.HikariDataSource : FirstPool - Start completed.
2020-03-05 15:34:05.159 INFO 11172 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-03-05 15:34:05.243 INFO 11172 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.4.10.Final}
2020-03-05 15:34:05.414 INFO 11172 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-03-05 15:34:05.554 INFO 11172 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.Oracle12cDialect
2020-03-05 15:34:06.519 INFO 11172 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-03-05 15:34:06.526 INFO 11172 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-03-05 15:34:06.853 WARN 11172 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-03-05 15:34:06.947 INFO 11172 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-03-05 15:34:07.115 INFO 11172 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-03-05 15:34:07.116 INFO 11172 --- [ main] be.myapp.ESPI.EspiApplication : Started EspiApplication in 5.135 seconds (JVM running for 5.744)
2020-03-05 15:34:17.044 INFO 11172 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-03-05 15:34:17.044 INFO 11172 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-03-05 15:34:17.052 INFO 11172 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms
2020-03-05 15:34:17.087 WARN 11172 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariConfig : SecondPool- maxLifetime is less than 30000ms, setting to default 1800000ms.
2020-03-05 15:34:17.087 INFO 11172 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : SecondPool- Starting...
2020-03-05 15:34:17.176 INFO 11172 --- [nio-8080-exec-1] com.zaxxer.hikari.pool.PoolBase : SecondPool- Driver does not support get/set network timeout for connections. (oracle.jdbc.driver.T4CConnection.getNetworkTimeout()I)
2020-03-05 15:34:17.178 INFO 11172 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : SecondPool- Start completed.
As you can see FirstPool is started. Spring Application starts. Then, only when needed, the SecondPool is started... I wonder how I can force the pool to start before the application starts ?
EDIT : My properties file are like this :
# DataSource definitions :
first.datasource.jdbc-url=jdbc:oracle:thin:@*a host*
first.datasource.username=user1
first.datasource.password=xxxxxxxxx
first.datasource.poolName=FirstPool
first.datasource.maximumPoolSize=100
first.datasource.maxLifetime=10000
second.datasource.jdbc-url=jdbc:oracle:thin:@*another host*
second.datasource.username=user2
second.datasource.password=xxxxxxxxx
second.datasource.poolName=SecondPool
second.datasource.maximumPoolSize=100
second.datasource.maxLifetime=10000
Second part :
# Profile definition
[email protected]@
# JPA definitions
spring.jpa.show-sql=true
spring.jpa.database=oracle
# DataSource
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.dataSourceClassName=oracle.jdbc.pool.OracleDataSource
spring.datasource.hikari.dataSourceProperties.implicitCachingEnabled=true
spring.datasource.hikari.dataSourceProperties.fastConnectionFailoverEnabled=true
# Oracle specifics
oracle.net.tns_admin=${ORACLE_HOME}/NETWORK/ADMIN
The configuration class that handle the DB Configuration :
@Configuration
@PropertySource({ "classpath:application.properties", "classpath:application-${spring.profiles.active}.properties"})
@Primary
public class DBConfiguration {
@Bean(name = "FirstDataSource")
@ConfigurationProperties("first.datasource")
@Primary
public HikariDataSource FirstDataSource() {
return (HikariDataSource) DataSourceBuilder.create().build();
}
@Bean(name = "SecondDataSource")
@ConfigurationProperties("second.datasource")
public HikariDataSource SecondDataSource() {
return (HikariDataSource) DataSourceBuilder.create().build();
}
@Bean(name="FirstTM")
@Autowired
@Primary
DataSourceTransactionManager FirstTM(@Qualifier ("FirstDataSource") DataSource datasource) {
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
return txm;
}
@Bean(name="SecondTM")
@Autowired
DataSourceTransactionManager SecondTM(@Qualifier("SecondDataSource") DataSource datasource) {
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
return txm;
}
}
I've found the answer.
So, first, the dataSources are all created, BUT, the pool attached to it are not created until asked. So the idea is to force their initialization when starting the application.
This can be achieved like this (see How to configure hikari pool for eager initialization? ):
You can use an ApplicationLoader
and get a connection at startup:
@Component
public class HikariLoader implements ApplicationRunner {
private final HikariDataSource hikariDataSource;
@Autowired
public HikariLoader(HikariDataSource hikariDataSource) {
this.hikariDataSource = hikariDataSource;
}
@Autowired
public void run(ApplicationArguments args) throws SQLException {
hikariDataSource.getConnection();
}
}