connection leak with c3p0 when testing
I have a particular situation that requires all data to be written to the DB during junit testing. I've been using the AbstractTransactionalDataSourceSpringContextTests but without configuring a txManager and also setting setDependencyCheck(false) to achieve this.
A side effect of this is that I now have to manually manage the session in the onSetUp() and onTearDown() methods to bind the session to the thread to stop lazyloading errors within the test.
My App Ctx is set up with a C3P0 connection pool :
Code:
lt;bean id=quot;dataSourcequot; class=quot;com.mchange.v2.c3p0.ComboPooledDataSourcequot; destroy-method=quot;closequot;gt; lt;property name=quot;driverClassquot; value=quot;oracle.jdbc.OracleDriverquot; /gt; lt;property name=quot;jdbcuclquot; value=quot;${jdbc.ucl}quot; /gt; lt;property name=quot;userquot; value=quot;${user}quot; /gt; lt;property name=quot;passwordquot; value=quot;${pass}quot; /gt; lt;property name=quot;minPoolSizequot; value=quot;0quot;/gt; lt;property name=quot;initialPoolSizequot; value=quot;1quot;/gt; lt;property name=quot;maxIdleTimequot; value=quot;10quot;/gt; lt;property name=quot;maxPoolSizequot; value=quot;50quot;/gt; lt;property name=quot;maxStatementsquot; value=quot;100quot;/gt; lt;property name=quot;checkoutTimeoutquot; value=quot;1500quot;/gt; lt;property name=quot;idleConnectionTestPeriodquot; value=quot;30quot;/gt; lt;/beangt;
Hibernate is configured : Code: lt;bean id=quot;hibernatePropertiesquot; class=quot;org..beans.factory.config.PropertiesFactoryBeanquot;gt; lt;property name=quot;propertiesquot;gt;lt;propsgt; lt;prop key=quot;hibernate.bytecode.use_reflection_optimizerquot;gt;falselt;/propgt; lt;prop key=quot;hibernate.cache.provider_classquot;gt;org.hibernate.cache.HashtableCacheProviderlt;/propgt; lt;prop key=quot;hibernate.cache.use_second_level_cachequot;gt;falselt;/propgt;lt;prop key=quot;hibernate.cache.use_query_cachequot;gt;truelt;/propgt; lt;prop key=quot;hibernate.connection.driver_classquot;gt;oracle.jdbc.OracleDriverlt;/propgt;lt;prop key=quot;hibernate.dialectquot;gt;org.hibernate.dialect.Oracle9Dialectlt;/propgt; lt;prop key=quot;hibernate.default_schemaquot;gt;${schema}lt;/propgt;lt;prop key=quot;hibernate.query.factory_classquot;gt;org.hibernate.hql.classic.ClassicQueryTranslatorFactorylt;/propgt;lt;prop key=quot;hibernate.query.substitutionsquot;gt;true 1, false 0lt;/propgt; lt;prop key=quot;hibernate.show_sqlquot;gt;truelt;/propgt; lt;prop key=quot;hibernate.jdbc.batch_sizequot;gt;0lt;/propgt; lt;prop key=quot;hibernate.connection.release_modequot;gt;after_transactionlt;/propgt;lt;/propsgt; lt;/propertygt; lt;/beangt;
The tests generally make a number of select, insert and delete calls to the DB via a DAO that extends the spring HibernateDaoSupport.
When the tests run (and with logging turned on) I see that the connections slowly increase with none of them being released back to the Pool. The onTearDown() method of the test case uses :
Code: SessionHolder sessionHolder =(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); Session session = sessionHolder.getSession(); SessionFactoryUtils.releaseSession(session,sessionFactory);
and when debugging the code, I can step through this onTearDown method, into the session.close and ultimately into where it calls NewPooledConnection.close(). From what I've read, providing you close the session, and the connection is closed this should be released back to the pool. Any ideas why not ?
If I set the property :
Code:
lt;property name=quot;unreturnedConnectionTimeoutquot; value=quot;10quot;/gt;
on my dataSource the this will forceably return the connections but accoring to the c3p0 docs is not recommended.
can you provide the mchange log? it should tell you if you have connection leak.
Thanks for your reply.
I've attached the log (zipped) - this is the mchange output from running 7 tests in a junit. From what I can see the number of connections increases to 13.
Your hibernation configuration release mode is set to after transaction. Even tho you closed your session, your connection will be not be released until the transaction is completed.
If I set the release mode to 'on_close' or 'auto' I get the same result.
My understanding of the way I've configured this (so that it always writes back to the DB) is that each call to dao will be in a transaction that ends (commits). Maybe I'm misunderstanding whats happening or perhaps there's another way to achieve this. |