使用hibernate数据库连接不释放的问题
最近同事遇到使用hibernate连接不释放的问题,代码大概是下面这样:
Query query = session.createQuery(hql); for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } List result = query.setFirstResult(offset).setMaxResults(pageSize).list();
看了代码就知道原因了,明显没有关闭连接,所以才会出现连接不释放的问题,应当手动调用session.close()
如果不想每次都要手动关闭连接,最好就不要使用上面的这种用法。简单点的化可以借助于HibernateDaoSupport来完成数据方法的执行,方法是你可以写个DAO类继承HibernateDaoSupport类就可以了。
为什么这样就不会有连接不释放的问题?
看看HibernateDaoSupport源码,你会发现其方法基本上都是类似下面的结构:
getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query query = session.getNamedQuery(queryName); ............ } });可以看到实际上HibernateDaoSupport中的方法最终都是调用HibernateTemplate类的execute方法,而execute方法最终都会调用doExecute方法,下面是doExecute方法的源码,主要看看finally代码块部分,就是在这里关闭的连接:
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Session session = (enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession()); boolean existingTransaction = (!enforceNewSession && (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory()))); if (existingTransaction) { logger.debug("Found thread-bound Session for HibernateTemplate"); } FlushMode previousFlushMode = null; try { previousFlushMode = applyFlushMode(session, existingTransaction); enableFilters(session); Session sessionToExpose = (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); T result = action.doInHibernate(sessionToExpose); flushIfNecessary(session, existingTransaction); return result; } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } catch (SQLException ex) { throw convertJdbcAccessException(ex); } catch (RuntimeException ex) { // Callback code threw application exception... throw ex; } finally {//在finally中关闭了session if (existingTransaction) { logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); disableFilters(session); if (previousFlushMode != null) { session.setFlushMode(previousFlushMode); } } else { // Never use deferred close for an explicitly new Session. if (isAlwaysUseNewSession()) { SessionFactoryUtils.closeSession(session); } else { SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); } } } }
综上,如果你是手动创建Query,那你要用完后必须要将session手动关闭。如果你是直接使用HibernateDaoSupport中的方法,那么不需要手动关闭session。或者你调用HibernateTemplate的方法也没有问题,类似getHibernateTemplate().execute(new HibernateCallback() {......})这样。
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇: 一个简单的例子让你理解值传递和引用传递