lukeda,
it was "c3p0.breakAfterAcquireFailure=true" that killed you here. From the resource pool's perspective, any time a pool is permanently marked broken without having been explicitly close()ed by a user, it's an expected break.
in the long listing above, what's going on is this:
1) you shut down the database. c3p0 tries to acquire Connections. some of these acquisition attempts are freezing rather than failing with an Exception, provoking the APPARENT DEADLOCK error.
[to resolve this, you can put a time limit on how long an acquisition attempt can hang via c3p0.maxAdministrativeTaskTime (since c3p0-0.9.1-pre7), which will cause tasks that fail to terminate properly to receive a Thread.interrupt() after the set time. 5 seconds is a good number. eventually these tasks do get interrupt()ed, but only after they have deemed to be deadlocked.]
2) eventually, a full round of acquisition attempts (10 in your case) fails. since c3p0.breakAfterAcquireFailure=true, the pool marks itself "unexpectedly broken" and all future attempts to work with it fail.
anyway, in practical terms, if you want c3p0 to survive database shutdowns and restarts, it's a good idea to leave "c3p0.breakAfterAcquireFailure=false", which is the default. for databases whose Connection acquisition attempts sometimes neither succeed nor fail promptly, setting c3p0.maxAdministrativeTaskTime=5-ish is a good idea too.
i'm not sure from your code whether you end up creating multiple pools, but you can test this (and log or fail if you are making more pools than you want) by using C3P0Registry methods, if the JMX stuff is inconvenient. C3P0Registry.allPooledDataSources().size() will tell you how many pools are currently running in the current VM (ClassLoader). If your app might be using non-default authentification information [i.e. explicitly calling dataSource.getConnection(user, pass)], there may be more than one pool per DataSource. I don't think hibernate's C3P0ConnectionProvider ever does this. But, if your app somehow does use multiple authentification info, code like this would give you the full pool count:
Code:
import com.mchange.v2.c3p0.*;
...
int getC3P0TotalPoolCount()
{
int count = 0;
for (Iterator ii = C3P0Registry.allPooledDataSources(); ii.hasNext();)
{
PooledDataSource pds = (PooledDataSource) ii.next();
count += pds.getNumUserPools();
}
return count;
}
I'll try to add a convenience method in C3P0Registry (and its associated MBean) for getting this information.
Good luck!
Steve