问题
In Hibernate 5 there are still big troubles with releasing database connections after initialization of lazy collection. Database connections after lazy initialization of collection are kept in "idle in transaction". So if many users work at the same time, count of open connections is increasing critically.
We use hibernate version 5.0.12, java version 1.8.0_151, jsf 2.3, don't use Spring (ORM).
There is reported issue for Hibernate version 3.2.7 - HHH-4808 - still opened. The last comment from july is 3 years later after this bug was reported and still not resolved in version 5.
I think we use recommended approach lazy loading of Hibernate. Even there exists a workaround (any drawback?) for version 4.2: Hibernate connections are not released after lazy collection initialization. Method
.getJdbcCoordinator().getLogicalConnection().aggressiveRelease()
from this workaround was removed in version 5.
I think a large number of developers have to use this lazy loading of very popular Hibernate, so I don't understand, why this issue is not resolved. So are there any solutions or verified workarounds?
回答1:
I am having the same problem. I can't believe this hasn't been fixed. Accessing collections through getters is a pretty important feature. Anyways, I was playing with the original workaround for 4.2 and found something that works for version 5. Try the following. It seems to work, but I have no idea what hidden side effects it may have.
@SuppressWarnings("serial")
public class CollectionEventListener extends DefaultInitializeCollectionEventListener
{
public void onInitializeCollection(InitializeCollectionEvent pEvent) throws HibernateException
{
super.onInitializeCollection(pEvent);
SessionImpl si = (SessionImpl) pEvent.getSession();
if (!si.isTransactionInProgress() && !si.isClosed() && si.isConnected()
&& si.getJdbcCoordinator().getLogicalConnection().getConnectionHandlingMode()
.getReleaseMode().equals(ConnectionReleaseMode.AFTER_TRANSACTION))
{
si.getJdbcCoordinator().afterTransaction();
}
}
}
回答2:
The same as FoxyBOA and Keith we are fiddling with a workaround how to close connection after lazy initialization of collection (for Hibernate version 5.) and there is our similar solution:
public class MyInitializeCollectionEventListener implements InitializeCollectionEventListener {
private static final long serialVersionUID = 1L;
DefaultInitializeCollectionEventListener defaultListener;
@Override
public void onInitializeCollection(InitializeCollectionEvent initializeCollectionEvent) throws HibernateException {
defaultListener.onInitializeCollection(initializeCollectionEvent);
SessionImpl si = (SessionImpl) initializeCollectionEvent.getSession();
if (!si.isTransactionInProgress() &&
!si.isClosed() &&
si.isConnected() &&
si.getJdbcCoordinator().getConnectionReleaseMode().equals(ConnectionReleaseMode.AFTER_TRANSACTION)){
si.getJdbcCoordinator().getLogicalConnection().afterTransaction();
}
}
It's working for all our tests, but if there are any drawbacks, I really don't know...
来源:https://stackoverflow.com/questions/47197940/hibernate-5-db-connections-are-still-not-released-idle-in-transaction-after-l