6

I'm new to stackoverflow, but read tons of posts here and now stuck.my application.properties is read, but the portion for configuring hikaricp is ignored/has no effect.

I read https://www.javadevjournal.com/spring-boot/spring-boot-hikari/ and folowed those steps there, still any success.

pom.xml

    <dependencies>  
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>5.4.10.Final</version>
        <exclusions>
            <exclusion>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
            </exclusion>
        </exclusions>
    </dependency>    
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jcache</artifactId>
        <version>5.4.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.6.3</version>
    </dependency>        
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </exclusion>                
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <exclusions>
         <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
         <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <exclusions>
    <exclusion>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <scope>test</scope>
        <version>2.2.2.RELEASE</version>
    </dependency>

application.properties

    spring.cache.jcache.config=classpath:ehcache.xml
    spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
    spring.datasource.username=vocapp202
    spring.datasource.password=******
    srping.datasource.driver-class-name=org.postgresql.Driver       
    spring.datasource.type=com.zaxxer.hikari.HikariDataSource
    spring.datasource.hikari.connectionTimeout=1000
    spring.datasource.hikari.idleTimeout=30000
    spring.datasource.hikari.maxLifetime=60000
    spring.datasource.hikari.connectionTestQuery=SELECT * FROM table where id=1
    spring.datasource.hikari.minimumIdle=1
    spring.datasource.hikari.maximumPoolSize=5
    spring.datasource.hikari.poolName=voiceapp-db-pool
    spring.datasource.hikari.autoCommit=false

BlacklistApplication.class:

    package de.mycompany.voice.blacklist_ng;  
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaAuditing;   
    @SpringBootApplication
    @EnableJpaAuditing
    @EnableCaching
    @Configuration
    public class BlacklistngApplication {

        public static void main(String[] args) {
            SpringApplication.run(BlacklistngApplication.class, args);
        }

    }

Config class:

    @Configuration
    @ConfigurationProperties("spring.datasource")
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactory",
            basePackages = {"de.firsttelecom.voice.blacklist_ng.repository.vocapp202"}
    )
    public class VocApp202DbConfig extends HikariConfig {

        @Primary
        @Bean(name = "dataSource")
        public DataSource dataSource() {
            return new HikariDataSource(this);
        }

What I'm missing?

shazin
  • 21,379
  • 3
  • 54
  • 71
  • How to use multiple datasources together with property binding is clearly explained in the reference guide. See https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-two-datasources. – M. Deinum Jan 27 '20 at 10:31
  • is this working for three data sources, too? or better n-sources. I have "huge" application or better different data sources from different departments which I need to combine in one application. – Marcus Stickler-Jäger Jan 27 '20 at 12:41
  • The fact that it mentions 2 doesn't mean it is limited to 2. The mechanism works for as many datasaources as you want. – M. Deinum Jan 27 '20 at 12:42
  • Good to know, thanks. – Marcus Stickler-Jäger Jan 27 '20 at 13:50
  • Don't add code/xml/stacktraces as comments. Those are unreadable. The solution in the documentation works, if it doesn't work for you you are doing things outside of the recommended way (or disable other parts of the auto-config). – M. Deinum Jan 27 '20 at 14:44

7 Answers7

4

spring.datasource.hikari.* (and also spring.datasource.url) properties will work only if you are using Spring Boot DataSource autoconfiguration. In order to achieve it, you need to remove this bean:

 @Primary
 @Bean(name = "dataSource")
 public DataSource dataSource() {
     return new HikariDataSource(this);
 }

Spring Boot will create it for you automatically using all these properties. You can check DataSourceAutoConfiguration.class for more information.

If, for some reason, you cannot remove this bean (f.e., you have another bunch of datasources, and you need to create your manual datasource in order to mark it as @Primary), you can use "raw" properties to configure hikari. So, instead of removing dataSource() method, you should modify your properties by removing hikari. part:

...
spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
...
spring.datasource.connectionTimeout=1000
spring.datasource.idleTimeout=30000
spring.datasource.maxLifetime=60000
spring.datasource.connectionTestQuery=SELECT * FROM table where id=1
spring.datasource.minimumIdle=1
spring.datasource.maximumPoolSize=5
spring.datasource.poolName=voiceapp-db-pool
spring.datasource.autoCommit=false

jdbc-url is also hikari-specific property, that's why it works now.

To summarize: properties without hikari. and with jdbc-url for manually created datasource beans, and properties with hikari. and url for Spring Boot DataSource autoconfiguration.

amseager
  • 5,795
  • 4
  • 24
  • 47
  • 2
    I just followed what you have mentioned above, gave raw properties to application.properties and used dataSource bean in java configuration and it worked like a charm! Reading your explanation in conjunction with https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-two-datasources really helped. Thanks! – kkk May 11 '20 at 09:51
  • 1
    This works for multiple Datasources too – inhaler Sep 06 '22 at 16:05
2

If you're already using application.properties file with hikari and datasource configuration, the moment you use new HikariDataSource(this) it will override your application.properties values.

You either create your HikariDataSource manually and remove from application.properties:

@Bean(name = "dataSource")
public DataSource dataSource() {
    HikariDataSource hikariDataSource = new HikariDataSource();
    hikariDataSource.setMaximumPoolSize(5);
    hikariDataSource.setMaxLifetime(60000);
    hikariDataSource.setMinimumIdle(1);

    //.. some other configs
    return hikariDataSource;
}

or use application.properties values only.

DaviM
  • 324
  • 2
  • 7
2

To keep configuration in standard format, and still create DataSource explicitly, connection pool specific prefix can be used for configuration properties. This is the same what spring boot DataSourceConfiguration does when auto-configuration is used:

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSourceProperties dataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariDataSource dataSource(DataSourceProperties properties) {
    HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    if (StringUtils.hasText(properties.getName())) {
        dataSource.setPoolName(properties.getName());
    }
    return dataSource;
}

Sample application.yaml:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres?gssEncMode=disable
    username: postgres
    password: postgres
    hikari:
      minimumIdle: 0
      maximumPoolSize: 50
      idleTimeout: 90000
      maxLifetime: 900000
      connectionTimeout: 45000
      leakDetectionThreshold: 45000
Andrey
  • 6,526
  • 3
  • 39
  • 58
0

but something did not work with application.properties, so I now did: DbConfig.class(es)

@Primary
@Bean(name = "dataSource")
public DataSource dataSource() {
    HikariConfig config = new HikariConfig("/hikari_voiceapp.properties");
    //HikariDataSource dataSource = new HikariDataSource(config);
    return new HikariDataSource(config);
}

and specify all params to each database in separate hikari.properties file including the name of database:

hikari_asterisk.properties
hikari_billing.properties
hikari_voiceapp.properties

works for me.

0

I used the following approach

second.datasource.jdbc-url=jdbc-url
second.datasource.username=username
second.datasource.password=password
.
.
.
.

=================== In Java Configuration File ==================

   @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix = "second.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("secondDataSource") DataSource dataSource) {
        Map<String, String> props = new HashMap<String, String>();
        props.put("spring.jpa.database-platform",  "org.hibernate.dialect.Oracle12cDialect");
.
.
.

        return builder.dataSource(dataSource).packages("com.second.entity").persistenceUnit("secondDB")
                .properties(props)
                .build();
    }

    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager secondTransactionManager(
            @Qualifier("secondEntityManagerFactory") EntityManagerFactory secondEntityManagerFactory) {
        return new JpaTransactionManager(secondEntityManagerFactory);
    }
Vikram
  • 179
  • 1
  • 7
0

I also faced to this problem. I like this solution:

My application.yml

spring:
    db1:
        datasource:
          jdbc-url: 'jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:postgres}'
          username: ${PG_USER}
          password: ${PG_PASS}
          driver-class-name: org.postgresql.Driver
          schema: file_integration_manager_dev
          maximum-pool-size: 2
          connection-timeout: 30000
          max-lifetime: 45000

My result config bean file:

@Bean(name = "datasource1")
    @ConfigurationProperties(prefix = "spring.db1.datasource")
    public DataSource dataSource() {
        return new HikariDataSource();
    }
0

In latest springboot version, there is no need to specify hikari in config. And properties should have hypen (-)

replace spring.datasource.hikari.maximumPoolSize=5
with spring.datasource.maximum-pool-size=5
Procrastinator
  • 2,526
  • 30
  • 27
  • 36