I'm using hibernate with c3p0, and as soon as the database is restarted, the application is broken with this error:
[warn] [com.mchange.v2.c3p0.impl.NewPooledConnection] [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
[warn] [com.mchange.v2.c3p0.impl.NewPooledConnection] [c3p0] Another error has occurred [ java.sql.SQLRecoverableException: Closed Connection ] which will not be reported to listeners!: java.sql.SQLRecoverableException: Closed Connection
at TypedQuery.getSingleResult()
.
I have to restart the application to fix it.
Yet, the EntityManager
is a singleton Bean created this way:
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(driverClassName);
cpds.setJdbcUrl(url);
cpds.setUser(user);
cpds.setPassword(password);
cpds.setPreferredTestQuery("SELECT 1 FROM dual");
cpds.setIdleConnectionTestPeriod(20);
cpds.setInitialPoolSize(0);
cpds.setMinPoolSize(0);
cpds.setMaxPoolSize(20);
cpds.setTestConnectionOnCheckin(true);
entityManagerFactory.setDataSource(cpds);
I don't understand why the connections are never replaced by the pool after the reboot of the database.
Would anyone know how if there is something wrong with the way I'm using c3p0 ?
Ok, it was not due to c3Pà nor Hibernate.
The bean in error was not managed by Spring, so it explicitly created a new c3p0 DataSource
at initialization, and didn't use the common c3p0 DataSource
.
The common DataSource
was visible with JMX, but not the other one, which means, I think, that the latter was simply no longer existing. This is confirmed by the fact that controllers using the common c3p0 DataSource
still work after database reboot, and the error was only thrown by the bean with dedicated DataSource
.
Just to finish the story, I solved my problem by reinitializing the dedicated c3p0 DataSource
in the bean, if an Exception is thrown.