Saurab Parakh
Saurab Parakh

Reputation: 1072

Hibernate Session is closed while using Transactional annotation on DAO class

I am getting this errpr

org.springframework.orm.hibernate3.HibernateSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)
    at org.springframework.orm.hibernate3.SpringSessionSynchronization.translateException(SpringSessionSynchronization.java:160)
    at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:148)
    at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:924)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:737)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622).
.....

   Caused by: org.hibernate.SessionException: Session is closed!
    at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:993)
.............`

My DAO Class

@Transactional 
@Repository(value = "flightBookingDao")
public class FltBookingDao {

  @Resource
  private GenericDaoService genericDaoService;

  public Flightbooking getFlightBookingObjByMmtid(final String mmtId) {

    final String SQL_QUERY = "from Flightbooking where fbkMmtid = '" + mmtId + "'";
    final List<Flightbooking> list = genericDaoService.executeNativeQuery(SQL_QUERY);
    if ((list == null) || (list.size() == 0)) {
        logger.debug("XXXX -- Getting null/empty flightBooking Object from DB -- XXXX");
        return null;
    } else {
        return list.get(0);
    }
}

@Service(value = "genericDaoService")
public class GenericDaoService extends HibernateDaoSupport  {

public List<Object> executeNativeQuery(final String queryString) {

    List<Object> list = null;
    final Session session = this.getSession();
    try {
        final Query query = session.createQuery(queryString);
        list = query.list();
    } catch (final Exception e) {
        LOGGER.error("XXX Error in executing query " + queryString + " XXX " + e);
    } finally {
        session.flush();
        session.close();
    }
    return list;
}

}

Configuration (I am just adding relevant configuration that I think is needed)

 <property name="mappingResources">
        <list>
            <value>com/yyy/bus/pojo/Flightbooking.hbm.xml</value>
        </list>
    </property>

 <property name="hibernateProperties">
        <props>
            <prop key="hibernate.current_session_context_class">
                ${hibernate.current_session_context_class}  // value is set to thread
            </prop>
        </props>
    </property>

     <context:component-scan base-package="com.yyy.bus.dao">

Upvotes: 2

Views: 4207

Answers (1)

Hunter Zhao
Hunter Zhao

Reputation: 4659

According to your code above, you are using Spring's TransactionManager to control transcation, that's to say you needn't to close session manually, TransactionManager will release the resource after you using it.
In one word, here are two solutions:
1,

session = this.getSession();  // retrive session from current thread
// do sth
// needn't close session manually

2,

session = this.getHibernateTemplate()
                .getSessionFactory().openSession(); // here open a new session
// do sth
session.close();

Upvotes: 4

Related Questions