Tutorial: Spring + Hibernate + HikariCP

HikariCP is newer JDBC connection pool, but has already gained a large following.  And for good reason!  It’s lightweight, reliable, and performant.

We recently added it as a core module to Hibernate ORM: hibernate-hikaricp (will be released in ORM 4.3.6 and 5.0.0).  However, I wanted to try and replace C3P0 within NeighborLink’s new web platform.  It’s been plagued with connection timeouts (regardless of the many iterations of config changes) and other quirks.  NL is based on Spring MVC and ORM (4.2.12), so in this setup, hibernate-hikaricp is a moot point.  We can simply feed the HikariCP DataSource implementation directly to the Spring LocalSessionFactoryBean.  Here’s my setup and configuration:

pom.xml

<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>1.3.6</version>
</dependency>

Spring Configuration

@Configuration
@EnableTransactionManagement
...
public class AppConfig {
 
    ...
 
    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setHibernateProperties(hibernateProperties());
 
        ...
 
        return sessionFactory;
    }
 
    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory().getObject());
 
        return txManager;
    }
 
    private DataSource dataSource() {
      ...
 
      final HikariDataSource ds = new HikariDataSource();
      ds.setMaximumPoolSize(100);
      ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
      ds.addDataSourceProperty("url", url);
      ds.addDataSourceProperty("user", username);
      ds.addDataSourceProperty("password", password);
      ds.addDataSourceProperty("cachePrepStmts", true);
      ds.addDataSourceProperty("prepStmtCacheSize", 250);
      ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
      ds.addDataSourceProperty("useServerPrepStmts", true);
      return ds;
    }
 
    private Properties hibernateProperties() {
        final Properties properties = new Properties();
        ... (Dialect, 2nd level entity cache, query cache, etc.)
        return properties;
    }
 
    ...
}

This setup also requires less maintenance, since rather than relying on Hibernate <-> HikariCP integration and supported versions, you sidestep that entirely and directly feed HikariCP into Spring.  This should theoretically allow you to use HikariCP with any version of Spring supporting Hibernate through a SessionFactoryBean.  Also note that although I’m using the annotation-based Spring configuration, the concepts would be similar through XML.