C3P0ConnectionProvider not getting closed on SessionFactory.close
Description
is duplicated by
is fixed by
Activity
Steve EbersoleMarch 20, 2014 at 7:55 PM
See the comments (and commits) on HHH-8923. The issue is fixed, but there is a question about how to best backport that (since it required an SPI change).
Steve EbersoleMarch 20, 2014 at 2:08 PM
As mentioned on HHH-8896, this is the result of an open design question wrt HIbernate's ServiceRegistry. See for details.

Claudio CarlenzoliJanuary 5, 2014 at 6:23 AMEdited
I've tried the suggested code in a J2EE Application Server Context (in particular Tomcat 7) and I've noticed this message
Tomcat Log
Looking in the source code of c3p0 (version 0.9.1 but in version 0.9.2.1 is always the same..) I've found an explanation
From com.mchange.v2.resourcepool.BasicResourcePool - part of method close(boolean)
com.mchange.v2.resourcepool.BasicResourcePool.java
I discovered that a part of procedure is performed by a Thread and this ends up with the SEVERE message reported.
In an environment of ServletContext redeploy I prefer to avoid this error message so I just add a
Thread.sleep(2000) //2 sec
statement to the suggested code just to give time to the close procedure.
workaround
It is a "not-normal" workaround but works...

Vernon WoodwardJanuary 22, 2013 at 5:56 PM
I am also experiencing this issue. If an application starts and stops within a JVM, the session pool stays open, even though the instantiating threads have stopped. By staying open the session pool does not release the database (using postgres) connections.
I generally see two threads, one of which is:
Daemon Thread [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1]

Shawn ClowaterNovember 19, 2012 at 7:18 PMEdited
I've also observed this behavior. By not calling close on the pool it leaves at least one background timer thread running holding a reference to the pool itself.
IIRC, I had tracked it down to the root cause of when the service registry is destroyed in the SessionFactory close it doesn't walk up the chain destroying the parents.
From AbstractServiceRegistryImpl
This only works on the direct serviceBindingList and doesn't destroy any of the parent services.
Details
Assignee
Brett MeyerBrett MeyerReporter
Jacob MoukaJacob MoukaLabels
Components
Affects versions
Priority
Major
Details
Details
Assignee

Reporter

The C3P0 connection pool does not get closed (and cleaned up) when the session factory is closed. This results in a memory leak when the app is undeployed/redeployed. Adding this bit of code (eg to a ServletContextListener.contextDestroyed) solves the issue:
private void closeSessionFactory(SessionFactory factory) {
if(factory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)factory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
factory.close();
}