title: JDBC connection timeout cannot reconnect
body: <p>I have my Spring Hibernate web application running on MySQL that gives me trouble.</p>
  
  <p>I have searched around and tried different configurations, read quite a few threads on this website, but it still pops up its smiling head.</p>
  
  <p>The error message is:
  Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 63,313,144 milliseconds ago.  The last packet sent successfully to the server was 63,313,144 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.</p>
  
  <pre><code>Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 63,313,144 milliseconds ago.  The last packet sent successfully to the server was 63,313,144 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
      at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
      at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1137)
      at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3965)
      at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2578)
      at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2758)
      at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2820)
      at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5359)
      at net.sf.log4jdbc.ConnectionSpy.setAutoCommit(ConnectionSpy.java:764)
      at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:912)
      at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72)
      at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162)
      at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435)
      at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61)
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:159)
      at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
      ... 46 more
  Caused by: java.net.SocketException: Broken pipe
      at java.net.SocketOutputStream.socketWrite0(Native Method)
      at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
      at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
      at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
      at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
      at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3946)
      ... 58 more
  </code></pre>
  
  <p>The MySQL wait_timeout value is 28800.</p>
  
  <p>My data source, c3p0 and Hibernate configuration is:</p>
  
  <pre><code>@Bean
  public DataSource dataSource() throws PropertyVetoException {
      ComboPooledDataSource dataSource = new ComboPooledDataSource();
      dataSource.setDriverClass(databaseProperties.getHibernateDriverClassName());
      dataSource.setJdbcUrl(databaseProperties.getDataSourceUrl());
      dataSource.setUser(databaseProperties.getDataSourceUsername());
      dataSource.setPassword(databaseProperties.getDataSourcePassword());
      dataSource.setAcquireIncrement(5);
      dataSource.setMaxStatementsPerConnection(20);
      dataSource.setMaxStatements(100);
      dataSource.setMinPoolSize(2);
      dataSource.setMaxPoolSize(5);
      return dataSource;
  }
  
  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws PropertyVetoException {
      HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
      jpaVendorAdapter.setDatabasePlatform(databaseProperties.getHibernateDialect());
      jpaVendorAdapter.setShowSql(true);
      jpaVendorAdapter.setGenerateDdl(false);
  
      Map&lt;String, String&gt; jpaPropertiesMap = new HashMap&lt;String, String&gt;();
      jpaPropertiesMap.put("hibernate.dialect", databaseProperties.getHibernateDialect());
      jpaPropertiesMap.put("hibernate.show_sql", "true");
      jpaPropertiesMap.put("hibernate.format_sql", "true");
      jpaPropertiesMap.put("hibernate.hbm2ddl.auto", databaseProperties.getHibernateHbm2ddlAuto());
      jpaPropertiesMap.put("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
      jpaPropertiesMap.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
      jpaPropertiesMap.put("hibernate.c3p0.min_size", "5");
      jpaPropertiesMap.put("hibernate.c3p0.max_size", "20");
      jpaPropertiesMap.put("hibernate.c3p0.timeout", "1000");
      jpaPropertiesMap.put("c3p0.maxConnectionAge", "7200");
      jpaPropertiesMap.put("c3p0.maxIdleTime", "7200");
      jpaPropertiesMap.put("c3p0.unreturnedConnectionTimeout", "60");
      jpaPropertiesMap.put("c3p0.debugUnreturnedConnectionStackTraces", "true");
      jpaPropertiesMap.put("hibernate.c3p0.max_statements", "50");
      // Prevent JPA from converting the dates to the UTC time zone
      jpaPropertiesMap.put("jadira.usertype.autoRegisterUserTypes", "true");
      jpaPropertiesMap.put("jadira.usertype.databaseZone", "jvm");
      jpaPropertiesMap.put("jadira.usertype.javaZone", "jvm");
  
      LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
      factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
      factoryBean.setPackagesToScan("com.nsn.nitro.project.data.jpa.domain");
      factoryBean.setJpaPropertyMap(jpaPropertiesMap);
      String[] mappingsResources = new String[] {"custom/typedef.hbm.xml"};        
      factoryBean.setMappingResources(mappingsResources);
      factoryBean.setDataSource(dataSource());
      return factoryBean;
  }
  </code></pre>
  
  <p>The error happens when the next morning I come back to the web application and it has not been accessed for the whole night.</p>
  
  <p>I understand that MySQL wait_timeout is the number of seconds MySQL will wait for a connection to be used again before closing it down.</p>
  
  <p>That means that my web application is trying to use a connection that has expired and been closed on MySQL side, with my web application still thinking it is a valid connection.</p>
  
  <p>I suppose I should then make my web application time out connections before MySQL does. This way, the web application would not reuse any connection already timed out and closed on MySQL side, since the connection would have already been timed out on the web application side.</p>
  
  <p>It feels like all my c3p0 configuration to that effect of timing out the unused connection is not doing its job.</p>
  
  <p>I'm using the following stack:</p>
  
  <pre><code>MySQL mysql-5.6.14
  mysql-connector-java 5.1.32
  Spring 4.1.0.RELEASE
  spring-data-jpa 1.6.2.RELEASE
  Hibernate 4.3.6.Final
  hibernate-jpa-2.1-api 1.0.0.Final
  C3P0 0.9.2.1
  </code></pre>
  
  <p>What am I doing wrong in my configuration ?</p>
  
  <p>Or am I supposed to explicitly close connections ?</p>
  
  <p>Here is how I set up the repositories:</p>
  
  <pre><code>public interface LanguageRepository extends GenericRepository&lt;Language, Long&gt; {
  }
  
  @Repository
  @Transactional
  public class GenericRepositoryImpl&lt;T, ID extends Serializable&gt; extends SimpleJpaRepository&lt;T, ID&gt; implements GenericRepository&lt;T, ID&gt; {
  
      private EntityManager entityManager;
  
      public GenericRepositoryImpl(JpaEntityInformation&lt;T, ID&gt; entityMetadata, EntityManager entityManager) {
          super(entityMetadata, entityManager);
  
          this.entityManager = entityManager;
      }
  
      public GenericRepositoryImpl(Class&lt;T&gt; domainClass, EntityManager entityManager) {
          super(domainClass, entityManager);
  
          this.entityManager = entityManager;
      }
  
      public EntityManager getEntityManager() {
          return entityManager;
      }
  
      @Override
      @Transactional
      public T deleteById(ID id) throws EntityNotFoundException {
          T entity = findOne(id);
          if (entity != null) {
              delete(entity);
          } else {
              throw new EntityNotFoundException("The entity could not be found and was not deleted");
          }
          return entity;
      }
  
  }
  
  public class GenericRepositoryFactoryBean&lt;R extends JpaRepository&lt;T, I&gt;, T, I extends Serializable&gt; extends JpaRepositoryFactoryBean&lt;R, T, I&gt; {
  
      protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
          return new BaseRepositoryFactory&lt;T, I&gt;(entityManager);
      }
  
      protected static class BaseRepositoryFactory&lt;T, I extends Serializable&gt; extends JpaRepositoryFactory {
  
          private EntityManager entityManager;
  
          public BaseRepositoryFactory(EntityManager entityManager) {
              super(entityManager);
  
              this.entityManager = entityManager;
          }
  
          @Override
          protected Object getTargetRepository(RepositoryMetadata metadata) {
              return new GenericRepositoryImpl&lt;T, I&gt;((JpaEntityInformation&lt;T, I&gt;) getEntityInformation(metadata.getDomainType()), entityManager);
          }
  
          @Override
          protected Class&lt;?&gt; getRepositoryBaseClass(RepositoryMetadata metadata) {
              return GenericRepositoryImpl.class;
          }
      }
  
  }
  
  @NoRepositoryBean
  public interface GenericRepository&lt;T, ID extends Serializable&gt; extends JpaRepository&lt;T, ID&gt; {
  
      public EntityManager getEntityManager();
  
      public T deleteById(ID id) throws EntityNotFoundException;
  
  }
  </code></pre>
  
  <p>I cannot see any close() method being implemented nor called in there. Something missing in my code ?</p>
  
  <p>EDIT: Added logging for C3P0. Here is what is output:</p>
  
  <pre><code>2014-10-17 14:29:00,464 INFO   [AbstractPoolBackedDataSource] Initializing c3p0 pool... com.mchange.
  v2.c3p0.ComboPooledDataSource [ acquireIncrement -&gt; 5, acquireRetryAttempts -&gt; 30, acquireRetryDelay
   -&gt; 1000, autoCommitOnClose -&gt; false, automaticTestTable -&gt; null, breakAfterAcquireFailure -&gt; false,
   checkoutTimeout -&gt; 0, connectionCustomizerClassName -&gt; null, connectionTesterClassName -&gt; com.mchan
  ge.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -&gt; agvw3s958cggbnis1syx|1acb901, debugUnretu
  rnedConnectionStackTraces -&gt; false, description -&gt; null, driverClass -&gt; net.sf.log4jdbc.DriverSpy, f
  actoryClassLocation -&gt; null, forceIgnoreUnresolvedTransactions -&gt; false, identityToken -&gt; agvw3s958c
  ggbnis1syx|1acb901, idleConnectionTestPeriod -&gt; 0, initialPoolSize -&gt; 3, jdbcUrl -&gt; jdbc:log4jdbc:my
  sql://127.0.0.1:3306/nitroproject, maxAdministrativeTaskTime -&gt; 0, maxConnectionAge -&gt; 0, maxIdleTim
  e -&gt; 0, maxIdleTimeExcessConnections -&gt; 0, maxPoolSize -&gt; 5, maxStatements -&gt; 100, maxStatementsPerC
  onnection -&gt; 20, minPoolSize -&gt; 2, numHelperThreads -&gt; 3, preferredTestQuery -&gt; null, properties -&gt; 
  {user=******, password=******}, propertyCycle -&gt; 0, statementCacheNumDeferredCloseThreads -&gt; 0, test
  ConnectionOnCheckin -&gt; false, testConnectionOnCheckout -&gt; false, unreturnedConnectionTimeout -&gt; 0, u
  serOverrides -&gt; {}, usesTraditionalReflectiveProxies -&gt; false ] 
  2014-10-17 14:29:00,479 DEBUG  [BasicResourcePool] incremented pending_acquires: 1 
  2014-10-17 14:29:00,480 DEBUG  [BasicResourcePool] Starting acquisition series. Incremented pending_
  acquires [1],  attempts_remaining: 30 
  2014-10-17 14:29:00,480 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchr
  onousRunner@11dbedc: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$Scattered
  AcquireTask@1dd75ae 
  2014-10-17 14:29:00,481 DEBUG  [BasicResourcePool] incremented pending_acquires: 2 
  2014-10-17 14:29:00,481 DEBUG  [BasicResourcePool] Starting acquisition series. Incremented pending_
  acquires [2],  attempts_remaining: 30 
  2014-10-17 14:29:00,482 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchr
  onousRunner@11dbedc: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$Scattered
  AcquireTask@15083c7 
  2014-10-17 14:29:00,482 DEBUG  [BasicResourcePool] incremented pending_acquires: 3 
  2014-10-17 14:29:00,483 DEBUG  [BasicResourcePool] Starting acquisition series. Incremented pending_
  acquires [3],  attempts_remaining: 30 
  2014-10-17 14:29:00,483 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchr
  onousRunner@11dbedc: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$Scattered
  AcquireTask@fbbf1d 
  2014-10-17 14:29:00,511 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:00,523 DEBUG  [C3P0PooledConnectionPool] com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager@e38aca.acquireResource() returning.  
  2014-10-17 14:29:00,523 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 1, unused: 1, excluded: 0] 
  2014-10-17 14:29:00,523 DEBUG  [BasicResourcePool] decremented pending_acquires: 2 
  2014-10-17 14:29:00,523 DEBUG  [BasicResourcePool] Acquisition series terminated successfully. Decremented pending_acquires [2],  attempts_remaining: 30 
  2014-10-17 14:29:00,521 DEBUG  [BasicResourcePool] com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 config: [start -&gt; 3; min -&gt; 2; max -&gt; 5; inc -&gt; 5; num_acq_attempts -&gt; 30; acq_attempt_delay -&gt; 1000; check_idle_resources_delay -&gt; 0; mox_resource_age -&gt; 0; max_idle_time -&gt; 0; excess_max_idle_time -&gt; 0; destroy_unreturned_resc_time -&gt; 0; expiration_enforcement_delay -&gt; 0; break_on_acquisition_failure -&gt; false; debug_store_checkout_exceptions -&gt; false] 
  2014-10-17 14:29:00,523 DEBUG  [C3P0PooledConnectionPoolManager] Created new pool for auth, username (masked): 'ni******'. 
  2014-10-17 14:29:00,523 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 1, unused: 0, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:00,524 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:00,525 DEBUG  [C3P0PooledConnectionPool] com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager@e38aca.acquireResource() returning.  
  2014-10-17 14:29:00,525 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 2, unused: 1, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:00,525 DEBUG  [BasicResourcePool] decremented pending_acquires: 1 
  2014-10-17 14:29:00,529 DEBUG  [BasicResourcePool] Acquisition series terminated successfully. Decremented pending_acquires [1],  attempts_remaining: 30 
  2014-10-17 14:29:00,525 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:00,530 DEBUG  [C3P0PooledConnectionPool] com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager@e38aca.acquireResource() returning.  
  2014-10-17 14:29:00,530 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:00,530 DEBUG  [BasicResourcePool] decremented pending_acquires: 0 
  2014-10-17 14:29:00,530 DEBUG  [BasicResourcePool] Acquisition series terminated successfully. Decremented pending_acquires [0],  attempts_remaining: 30 
  2014-10-17 14:29:00,562 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:00,574 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchronousRunner@11dbedc: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@1fec09e 
  2014-10-17 14:29:00,574 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:00,575 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:00,575 DEBUG  [NewProxyConnection] com.mchange.v2.c3p0.impl.NewProxyConnection@39069f: close() called more than once. 
  2014-10-17 14:29:02,260 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePool@ad2e72 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:03,111 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:03,112 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchronousRunner@11dbedc: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@146219b 
  2014-10-17 14:29:03,112 DEBUG  [GooGooStatementCache] checkinAll(): com.mchange.v2.c3p0.stmt.DoubleM
  axStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 
  2014-10-17 14:29:03,113 DEBUG  [BasicResourcePool] trace com.mchange.v2.resourcepool.BasicResourcePo
  ol@ad2e72 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@acde7c) 
  2014-10-17 14:29:03,262 DEBUG  [DefaultListableBeanFactory] Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
  2014-10-17 14:29:03,285 DEBUG  [DefaultListableBeanFactory] Finished creating instance of bean 'entityManagerFactory' 
  </code></pre>
  
  <p>And then it loops outputting this:</p>
  
  <pre><code>2014-10-17 14:34:10,399 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@70b40a -- Running DeadlockDetector[Exiting. No pending tasks.] 
  2014-10-17 14:34:10,825 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@15e34e2 -- Running DeadlockDetector[Exiting. No pending tasks.] 
  2014-10-17 14:34:10,825 DEBUG  [ThreadPoolAsynchronousRunner] com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@15e34e2 -- Running DeadlockDetector[Exiting. No pending tasks.]
  </code></pre>