How do I configure HikariCP in my Spring Boot app in my application.properties files?

313,403

Solution 1

@Configuration
@ConfigurationProperties(prefix = "params.datasource")
public class JpaConfig extends HikariConfig {

    @Bean
    public DataSource dataSource() throws SQLException {
        return new HikariDataSource(this);
    }

}

application.yml

params:
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/myDb
    username: login
    password: password
    maximumPoolSize: 5

UPDATED! Since version Spring Boot 1.3.0 :

  1. Just add HikariCP to dependencies
  2. Configure application.yml

application.yml

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:h2:mem:TEST
    driver-class-name: org.h2.Driver
    username: username
    password: password
    hikari:
      idle-timeout: 10000

UPDATED! Since version Spring Boot 2.0.0 :

The default connection pool has changed from Tomcat to Hikari :)

Solution 2

I came across HikariCP and I was amazed by the benchmarks and I wanted to try it instead of my default choice C3P0 and to my surprise I struggled to get the configurations right probably because the configurations differ based on what combination of tech stack you are using.

I have setup Spring Boot project with JPA, Web, Security starters (Using Spring Initializer) to use PostgreSQL as a database with HikariCP as connection pooling.
I have used Gradle as build tool and I would like to share what worked for me for the following assumptions:

  1. Spring Boot Starter JPA (Web & Security - optional)
  2. Gradle build too
  3. PostgreSQL running and setup with a database (i.e. schema, user, db)

You need the following build.gradle if you are using Gradle or equivalent pom.xml if you are using maven

buildscript {
    ext {
        springBootVersion = '1.5.8.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'

group = 'com'
version = '1.0'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-aop')

    // Exclude the tomcat-jdbc since it's used as default for connection pooling
    // This can also be achieved by setting the spring.datasource.type to HikariCP 
    // datasource see application.properties below
    compile('org.springframework.boot:spring-boot-starter-data-jpa') {
        exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
    }
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('org.postgresql:postgresql')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.security:spring-security-test')

    // Download HikariCP but, exclude hibernate-core to avoid version conflicts
    compile('com.zaxxer:HikariCP:2.5.1') {
        exclude group: 'org.hibernate', module: 'hibernate-core'
    }

    // Need this in order to get the HikariCPConnectionProvider
    compile('org.hibernate:hibernate-hikaricp:5.2.11.Final') {
        exclude group: 'com.zaxxer', module: 'HikariCP'
        exclude group: 'org.hibernate', module: 'hibernate-core'
    }
}

There are a bunch of excludes in the above build.gradle and that's because

  1. First exclude, instructs gradle that exclude the jdbc-tomcat connection pool when downloading the spring-boot-starter-data-jpa dependencies. This can be achieved by setting up the spring.datasource.type=com.zaxxer.hikari.HikariDataSource also but, I don't want an extra dependency if I don't need it
  2. Second exclude, instructs gradle to exclude hibernate-core when downloading com.zaxxer dependency and that's because hibernate-core is already downloaded by Spring Boot and we don't want to end up with different versions.
  3. Third exclude, instructs gradle to exclude hibernate-core when downloading hibernate-hikaricp module which is needed in order to make HikariCP use org.hibernate.hikaricp.internal.HikariCPConnectionProvider as connection provider instead of deprecated com.zaxxer.hikari.hibernate.HikariConnectionProvider

Once I figured out the build.gradle and what to keep and what to not, I was ready to copy/paste a datasource configuration into my application.properties and expected everything to work with flying colors but, not really and I stumbled upon the following issues

  • Spring boot failing to find out database details (i.e. url, driver) hence, not able to setup jpa and hibernate (because I didn't name the property key values right)
  • HikariCP falling back to com.zaxxer.hikari.hibernate.HikariConnectionProvider
  • After instructing Spring to use new connection-provider for when auto-configuring hibernate/jpa then HikariCP failed because it was looking for some key/value in the application.properties and was complaining about dataSource, dataSourceClassName, jdbcUrl. I had to debug into HikariConfig, HikariConfigurationUtil, HikariCPConnectionProvider and found out that HikariCP could not find the properties from application.properties because it was named differently.

Anyway, this is where I had to rely on trial and error and make sure that HikariCP is able to pick the properties (i.e. data source that's db details, as well as pooling properties) as well as Sping Boot behave as expected and I ended up with the following application.properties file.

server.contextPath=/
debug=true

# Spring data source needed for Spring boot to behave
# Pre Spring Boot v2.0.0.M6 without below Spring Boot defaults to tomcat-jdbc connection pool included 
# in spring-boot-starter-jdbc and as compiled dependency under spring-boot-starter-data-jpa
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/somedb
spring.datasource.username=dbuser
spring.datasource.password=dbpassword

# Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000

# Without below HikariCP uses deprecated com.zaxxer.hikari.hibernate.HikariConnectionProvider
# Surprisingly enough below ConnectionProvider is in hibernate-hikaricp dependency and not hibernate-core
# So you need to pull that dependency but, make sure to exclude it's transitive dependencies or you will end up 
# with different versions of hibernate-core 
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider

# JPA specific configs
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql=true
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.default_schema=dbschema
spring.jpa.properties.hibernate.search.autoregister_listeners=false
spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false

# Enable logging to verify that HikariCP is used, the second entry is specific to HikariCP
logging.level.org.hibernate.SQL=DEBUG
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE 

As shown above the configurations are divided into categories based on following naming patterns

  • spring.datasource.x (Spring auto-configure will pick these, so will HikariCP)
  • spring.datasource.hikari.x (HikariCP picks these to setup the pool, make a note of the camelCase field names)
  • spring.jpa.hibernate.connection.provider_class (Instructs Spring to use new HibernateConnectionProvider)
  • spring.jpa.properties.hibernate.x (Used by Spring to auto-configure JPA, make a note of the field names with underscores)

It's hard to come across a tutorial or post or some resource that shows how the above properties file is used and how the properties should be named. Well, there you have it.

Throwing the above application.properties with build.gradle (or at least similar) into a Spring Boot JPA project version (1.5.8) should work like a charm and connect to your pre-configured database (i.e. in my case it's PostgreSQL that both HikariCP & Spring figure out from the spring.datasource.url on which database driver to use).

I did not see the need to create a DataSource bean and that's because Spring Boot is capable of doing everything for me just by looking into application.properties and that's neat.

The article in HikariCP's github wiki shows how to setup Spring Boot with JPA but, lacks explanation and details.

The above two file is also availble as a public gist https://gist.github.com/rhamedy/b3cb936061cc03acdfe21358b86a5bc6

Solution 3

You could simply make use of application.yml/application.properties only. There is no need to explicitly create any DataSource Bean

You need to exclude tomcat-jdbc as mentioned by ydemartino

<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>
</dependency>

As you won't create DataSource bean, you have to explicitly specify using Hikari through spring.datasource.type with value com.zaxxer.hikari.HikariDataSource in application.yml / application.properties

spring:
    datasource:
        hikari:
            connection-test-query: SELECT 1 FROM DUAL
            minimum-idle: 1
            maximum-pool-size: 5
            pool-name: yourPoolName
            auto-commit: false
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/myDb
        username: login
        password: password
        type: com.zaxxer.hikari.HikariDataSource

In your application.yml / application.properties, you could configure Hikari specific parameters such as pool size etc in spring.datasource.hikari.*

Solution 4

I'm using Spring Boot 2.0.4.RELEASE. Hikari is default connection pool and .hikari is no longer necessary.

application.properties

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.jdbcUrl=jdbc:mysql://localhost:3306/myDB...
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.poolname=myPool

application.yml

spring:
    datasource:
        driverClassName: com.mysql.jdbc.Driver
        jdbcUrl: jdbc:mysql://localhost:3306/myDB...
        username: xxx
        password: xxx
        poolName: myPool

And configuration does not need to extend HikariConfig, and DataSourceBuilder can be used as it was before.

@Configuration
public class DataSourceConfiguration {

    @Bean(name="myDataSource")
    @ConfigurationProperties("spring.datasource")
    public DataSource myDataSource() {
        return DataSourceBuilder.create().build();
    }
}

Solution 5

You don't need redundant code for putting property values to variables. You can set properties with a properties file directly.

Put hikari.properties file in the classpath.

driverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/myDb
connectionTestQuery=SELECT 1
maximumPoolSize=20
username=...
password=...

And make a datasource bean like this.

@Bean(destroyMethod = "close")
public DataSource dataSource() throws SQLException {
    HikariConfig config = new HikariConfig("/hikari.properties");
    HikariDataSource dataSource = new HikariDataSource(config);

    return dataSource;
}
Share:
313,403

Related videos on Youtube

Kevin M
Author by

Kevin M

Updated on July 08, 2022

Comments

  • Kevin M
    Kevin M almost 2 years

    I'm trying to set up HikariCP in my Spring Boot (1.2.0.M1) app so I can test using it in place of Tomcat DBCP. I'd like to configure the connection pool in my application.properties file like I was doing with Tomcat, but I can't figure out how I should be doing it. All examples I've found show either JavaConfig style, or using a separate HikariCP properties file. Can someone help me figure out the property names to configure it in application.properties? I'd like to also switch from using the driverClassName approach to the DataSourceClassName approach since it looks cleaner and is recommended. Is this also possible in my application.properties file(s)?

    Here's what I had for Tomcat DBCP (just some basic config, not fully flushed out)

    spring.datasource.validation-query=SELECT 1
    spring.datasource.max-active=10
    spring.datasource.max-idle=8
    spring.datasource.min-idle=8
    spring.datasource.initial-size=5
    spring.datasource.test-on-borrow=true
    spring.datasource.test-on-return=true
    

    And I'm currently using driverClassName and jdbc url to set up the connection:

    spring.datasource.url=jdbc:mysql://localhost:3306/myDb
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    
    • geoand
      geoand over 9 years
      What version of Spring Boot are you using?
    • Kevin M
      Kevin M over 9 years
      1.2.0.M1 I think I might have figured out how to set the properties to set things like maximumPoolSize for hikariCP. But I have been unable to get the configuration working using the hikariCP recommended way using dataSourceClassName and serverName instead of driverClassName and jdbc url. So I gave up on that part. If someone can figure that part, that'd help
    • geoand
      geoand over 9 years
      I'll give 1.2.0.M1 a try later on, and I find out anything I'll post it
    • Andy Wilkinson
      Andy Wilkinson over 9 years
      You can't use the dataSourceClassName approach with Spring Boot's auto-configuration of a DataSource as it requires that spring.datasource.url is set. Note that you don't need to specify driverClassName as Boot will infer it from jdbcUrl.
    • kinjelom
      kinjelom almost 7 years
      application.properties: spring.datasource.hikari.*, documentation: github.com/brettwooldridge/HikariCP
    • Kevin M
      Kevin M almost 7 years
      Thanks for updating. Originally, back in 2014, this was how they were specified.
  • Jesús Zazueta
    Jesús Zazueta about 9 years
    It is. It's easily translatable to Java though.
  • Kevin M
    Kevin M about 9 years
    Yeah I'm realizing now that I need to do this because now I want to configure the Metrics. And the only way I can see to do that is with this JavaConfig to override the autoconfiguration. Thanks.
  • Davi Alves
    Davi Alves almost 9 years
    I've been using HikariCP for some time in different applications, and so far never had any problem. I'm using the HikariConfig approach, where you have all your configuration on a properties file. Works as expected with SpringBoot and SpringCore as well. I'm also configuring the maximumPoolSize.
  • Jesús Zazueta
    Jesús Zazueta over 8 years
    I think this is a much better, more portable approach. Cheers!
  • Tomas Hanus
    Tomas Hanus over 8 years
    This could be used for standard spring configuration as well, but one think is important. Hikari used url of datasource via jdbcUrl, but spring via url. { private String url; @Bean public DataSource dataSource() throws SQLException { return new HikariDataSource(this); } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; // HikariConfig hold JDBC-URL in jdbcUrl property, but spring provides this property as url this.setJdbcUrl(url); } }
  • Joao Polo
    Joao Polo over 8 years
    Yes, it helps! You get my opvote too... Is it groovie? It's very interesting, it's like javascript :-)
  • Michael Piefel
    Michael Piefel over 7 years
    You do not need to exclude the Tomcat to make this work, adding spring.datasource.type is enough.
  • Jan Bodnar
    Jan Bodnar about 7 years
    @MichaelPiefel You need to do the exclusion. The javadoc of DataSourceBuilder says: If Tomcat, HikariCP or Commons DBCP are on the classpath one of them will be selected (in that order with Tomcat first). My testing confirms this.
  • Michael Piefel
    Michael Piefel about 7 years
    @JanBodnar: DataSourceConfiguration, which is used in auto-configuration, has the configurations depending on spring.datasource.type if it is set at all. So, I have tomcat-jdbc on my classpath, and still use HikariCP as my pool. My testing confirms this. Maybe we are talking about very different Spring Boot versions here.
  • Jan Bodnar
    Jan Bodnar about 7 years
    @MichaelPiefel Interestingly, I've managed to run it OK without the exclusion with Java config only by using DataSourceBuilder.create()...type(com.zaxxer.hikari.HikariDa‌​taSource.class). With configuration in the yaml file, it did not work for me. So there has to be some catch.
  • sura2k
    sura2k about 7 years
    It should be spring.datasource.maximum-pool-size when you use spring config properties, otherwise maximumPoolSize is the HikariCP parameter name.
  • bluelabel
    bluelabel almost 7 years
    Sorry this is a bit late reply, but @Sergey solution should slightly be changed in order to get all properties. To get hikari specific DS properties, you need to set the key as "spring.datasource. dataSourceProperties" instead "spring.datasource.hikari"
  • Bogdan Pușcașu
    Bogdan Pușcașu over 6 years
    I was struggling with this right before you posted. Thank you!
  • Raf
    Raf over 6 years
    Glad it helped you! 👍
  • Matthew Fontana
    Matthew Fontana over 6 years
    Raf you have an awesome answer. I was curious if it would be possible for you to post the changes needed for Spring Boot 2.0.0.M6 . Struggling with the configuration not being picked up and the Migration Guide isn't updated yet
  • Raf
    Raf over 6 years
    Hey Mat, I was using 1.5.8 Release when I shared my solution here. I wanted to give 2.0.0.M6 a quick try but, unfortunately they require you to have a higher version of gradle. The only change I can remember in 2.0.0.M6 would be making HikariCP default connection pooling for spring jpa see here github.com/spring-projects/spring-boot/commit/… Try debugging HikariConfig, HikariConfigurationUtil, HikariCPConnectionProvider to make sure that properties is picked up.
  • comiventor
    comiventor about 6 years
    this was super helpful, although I had to figure out few property names not mentioned here like stringType to configure data source props.
  • supertonsky
    supertonsky about 6 years
    Before, we just needed to see how it is configured by looking at the datasource's documentation, now it got worse, we also now need to know how it is configured when using Spring Boot. I don't really see this automagic configuration is really helping us.
  • Shahid Yousuf
    Shahid Yousuf almost 6 years
    Good to know it helped.
  • mertaksu
    mertaksu about 5 years
    spring.datasource.hikari.maximum-pool-size=500 really horrible and it is not recommended from hikari :) github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
  • Philip Dilip
    Philip Dilip almost 5 years
    That was just a sample configuration with Values :)
  • Mauro Molinari
    Mauro Molinari almost 4 years
    This reply is valuable for providing a working example with data-source-properties!
  • AnOttawan
    AnOttawan about 3 years
    I just wasted several hours trying to get this to work, but hikari was ignoring my config params in the yml file (max pool size in my case). In case anyone else runs into this: do not forget to indent the parameters under hikari!! The example in this post is correct, but in mine I had my maximum-pool-size lined up under the 'h' of hikari instead of indented 2 spaces...