使用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。
- 上一篇:没有了
- 下一篇: 一个简单的例子让你理解值传递和引用传递
