ERROR: Operation not allowed after ResultSet closed Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not get next iterator result Caused by: java.sql.SQLException: Operation not allowed after ResultSet closed
以下是DAO类,没有使用注解事务.(以下只截取了部分代码)
@Repository("forumHibernateDao") //@Transactional public class ForumHibernateDao extends BaseDao{ public long getForumNum(){ Object obj = getHibernateTemplate().iterate("select count(f.forumId) from Forum f").next(); return (Long) obj; } }
先说结论:在调用getForumNum()方法的时候报文章开头的错误,在给DAO加上事务后就正常了。
下面看看代码为什么这样。
1.跳转到HibernateTemplate类Iterator<?> iterate()方法中。
public Iterator<?> iterate(final String queryString, final Object... values) throws DataAccessException { return (Iterator)this.executeWithNativeSession(new HibernateCallback<Iterator<?>>() { public Iterator<?> doInHibernate(Session session) throws HibernateException { Query queryObject = session.createQuery(queryString); HibernateTemplate.this.prepareQuery(queryObject); if(values != null) { for(int i = 0; i < values.length; ++i) { queryObject.setParameter(i, values[i]); } } return queryObject.iterate(); } }); }
2. 接着执行HibernateTemplate类的executeWithNativeSession(HibernateCallback<T> action),再执行doExecute(HibernateCallback<T> action, boolean enforceNativeSession),代码如下(重点看划线部分):
public <T> T executeWithNativeSession(HibernateCallback<T> action) { return this.doExecute(action, true); } protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); //初始化session [u]Session session = null;[/u] boolean isNew = false; try { //通过SessionFactory得到session, 此处所得session为null //如果有事务注解,则此处所得session非空 [u]session = this.getSessionFactory().getCurrentSession();[/u] } catch (HibernateException var12) { this.logger.debug("Could not retrieve pre-bound Hibernate session", var12); } //如果有事务注解,则此处所得session非空判断,isNew仍未false if(session == null) { //session为空则open session. [u]session = this.getSessionFactory().openSession();[/u] session.setFlushMode(FlushMode.MANUAL); //设置isNew为true [u]isNew = true;[/u] } Object var6; try { this.enableFilters(session); Session sessionToExpose = !enforceNativeSession && !this.isExposeNativeSession()?this.createSessionProxy(session):session; //调用doInHibernate方法,进行持久化。 [u]var6 = action.doInHibernate(sessionToExpose);[/u] } catch (HibernateException var13) { throw SessionFactoryUtils.convertHibernateAccessException(var13); } catch (RuntimeException var14) { throw var14; } finally { //isNew为true,所以此处关闭session. //如果有事务注解,isNew为false,session不会关闭。 if(isNew) { SessionFactoryUtils.closeSession(session); } else { this.disableFilters(session); } } return var6; }
以上说明在无事务调用next()方法时, session已经关闭,所以在接着调用next()方法的时候抛出异常报错;而若存在事务,则session不会关闭,则可正确调用该方法。