Hibernate 5:延迟加载后仍未释放数据库连接(在事务中空闲)

时间:2017-11-09 09:16:36

标签: java hibernate database-connection connection-pooling lazy-initialization

在Hibernate 5中,在初始化延迟集合之后释放数据库连接仍然存在很大的麻烦。延迟初始化收集后的数据库连接保持在"空闲的事务"中。因此,如果许多用户同时工作,那么开放连接的数量正在急剧增加。

我们使用 hibernate版本5.0.12 java版本1.8.0_151 jsf 2.3 ,不使用Spring(ORM) )。

Hibernate版本3.2.7报告了问题 - HHH-4808 - 仍然打开。 7月后的最后一条评论是在报告此错误后3年后仍未在第5版中解决的。

我认为我们使用推荐的方法延迟加载Hibernate。即使版本4.2存在变通方法(任何缺点?):Hibernate connections are not released after lazy collection initialization。方法      此版本中的.getJdbcCoordinator().getLogicalConnection().aggressiveRelease()已在版本5中删除。

我认为大量的开发人员必须使用这种非常流行的Hibernate的延迟加载,所以我不明白,为什么这个问题没有得到解决。那么有任何解决方案或经过验证的解决方法吗?

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。我不敢相信这个问题没有得到解决。通过getter访问集合是一个非常重要的功能。无论如何,我正在玩4.2的原始解决方法,并发现适用于版本5的东西。尝试以下。它似乎有效,但我不知道它可能有什么隐藏的副作用。

@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();
      }
   }
}

答案 1 :(得分:0)

FoxyBOAKeith相同,我们正在摆弄 解决方法如何在延迟初始化集合后关闭连接(对于Hibernate版本5.)并且有类似的解决方案:

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();
    }
}

它适用于我们所有的测试,但如果有任何缺点,我真的不知道......