0

Environment: Ubuntu 14.04.4

Application in development details: Spring 4.2.5.RELEASE MVC webapp, MySQL with 151 + 1 MAX_CONNECTIONS, Hibernate, HikariCP as datasource with 20 connections per pool, 1 pool.

Automated deployment tool: Jenkins

Deployment container: Tomcat 7

Pre-requisites:
1. Application already started and working, accessible through web.

Use-case:
1. Login to mysql command line and execute: show processlist;
2. Observe 20 connections + 1, yours in command line.
3. Trigger new build in Jenkins, and wait deployment of the new *.war to the tomcat
4. execute: show processlist; in mysql command line
5. Observe 40 connections + 1, yours in command line.
6. Observe increase in connections up to MAX_CONNECTIONS + 1, and after this the Jenkins fails to build because the unit tests which require a DB fail.

Expected: 20 connections at most in the case when application is accessed, and no connections at all if application is idle (this is the behavior observed by me on my local development Windows 8.1 Pro Machine)

HikariCP data source details:

@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean sessionFactory = new LocalContainerEntityManagerFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan("com.myapp");

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    sessionFactory.setJpaVendorAdapter(vendorAdapter);
    sessionFactory.setJpaProperties(hibernateProperties());

    return sessionFactory;
}

private DataSource dataSource() {

    final HikariDataSource ds = new HikariDataSource();
    ds.setMaximumPoolSize(20);
    ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
    ds.addDataSourceProperty("url", "jdbc:mysql://localhost/myapp");
    ds.addDataSourceProperty("user", "usr");
    ds.addDataSourceProperty("password", "pwd");
    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();
    properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    properties.put("hibernate.hbm2ddl.auto", "validate");
    properties.put("hibernate.implicit_naming_strategy", "legacy-jpa");
    return properties;
}

It seems that the connections are not released, even after re-deployment of the application. Any ideas?

XMight
  • 1,991
  • 2
  • 20
  • 36

1 Answers1

0

Ended up doing the following:

public class MyLocalContainerEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {

public static final LoggerWrapper logger = new LoggerWrapper(MyLocalContainerEntityManagerFactoryBean.class);

@Override
public void destroy() {

    logger.warning("Destroying MyLocalContainerEntityManagerFactoryBean!");

    DataSource ds = getDataSource();
    if(ds instanceof HikariDataSource) {
        HikariDataSource hds = (HikariDataSource)ds;

        logger.warning("Closing the Hikari data source!");
        hds.close();
    }

    super.destroy();
}

}

Now everything works as expected, even after several deploy/re-deploy actions!

XMight
  • 1,991
  • 2
  • 20
  • 36