Nov 24th, 2008, 07:02 AM
HibernateJpaDialect doesn’t release borrowed connection after TX completion
We use JPA with Hibernate in standalone mode, that is we inject DriverManagerDataSource into EntityManagerFactory. We implement flow managed persistence context using spring webflow 1.0.5, in which we keep EntityManager object open until the end of a flow. We don't modify default connection release mode of Hibernate, which is AFTER_TRANSACTION for JdbcTransactionFactory in our case.
We see that JpaTransactionManager calls HibernateJpaDialect.getJdbcConnection() method to get JDBC connection in order to expose JpaTransactionObject as JdbcTransactionObject during TX begin phase. The returned connection from getJdbcConnection() method is a borrowed connection as Hibernate Session.connection() method is called.
After transaction completion JpaTransactionManager cleans up any resources as expected. However as it does nothing in releaseJdbcConnection() method, a reference is kept to this borrowed connection in Hibernate’s ConnectionManager class after TX completion.
This doesn’t cause any problem during TX completion, and Hibernate closes open JDBC connection at this point. However, any connection acquired without an active TX after this point, for example accessing a lazy association causes a new JDBC connection to open, will not be released by Hibernate as previously borrowed connection is not released.
The open connection will be kept until a new TX is executed or EntityManager is closed. We want to know that it is a bug to not to release borrowed connection in HibernateJpaDialect by overriding DefaultJpaDialect.releaseJdbcConnection()? Hibernate API says in Session.connection() method that it is application’s responsibility to close connection if it is acquired using this method. When we override releaseJdbConnection() and call conHandle.getConnection().close() in it, borrowed connection is released in Hibernate’s ConnectionManager class, and connections acquired outside of a TX is released after any statement execution. Might this modification to HibernateJpaDialect cause any unforseen issues in our configuration?
Thanks in advance
Dec 1st, 2008, 02:28 AM
After a more detailed inspection, we saw that cleanup() method, in which borrowed connection is released as well, is expected to be called in three points in Hibernate's ConnectionManager class; 1.after session close, 2.after manual disconnect of Hibernate session, and 3.after transaction completion. Although there are calls to cleanup() method in first two points, there is no call in the third one, specifically afterTransaction() method in ConnectionManager.
I think, it was Hibernate's responsibility to release borrowed connection at the end of transaction. At this moment, it seems that the most appropriate place to release borrowed connection outside Hibernate is HibernateJpaDialect's releaseJdbcConnection method.
Tags for this Thread