Back Forum Reply New

HibernateException: No Hibernate Session bound to thread

I am getting this exception when I call a DAO method which uses SessionFactory.getCurrentSession().  The DAO class is annotated with @Transactional and I also have lt;tx:annotation-driven/gt; declared in the application context configuration file.

I can call my DAO methods which perform HQL queries, but whenever I call a DAO method which first gets the Hibernate session then I run into this exception:Code:   SEVERE: Failed to save the object.   org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

I have the following application context configuration file:Code:   lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;   lt;beans xmlns=quot;schema/beansquot;          xmlns:aop=quot;schema/aopquot;          xmlns:flex=quot;schema/flexquot;          xmlns:tx=quot;schema/txquot;          xmlns:xsi=quot;2001/XMLSchema-instancequot;          xsi:schemaLocation=quot;schema/beans                   schema/beans/spring-beans-2.5.xsd                   schema/flex                   schema/flex/spring-flex-1.0.xsd                   schema/tx                   schema/tx/spring-tx-2.0.xsdquot;gt;              lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;!--  load values used for bean properties  --gt;       lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;bean class=quot;org..beans.factory.config.PropertyPlaceholderConfigurerquot;gt;lt;property name=quot;locationsquot;gt;    lt;valuegt;applicationContext.propertieslt;/valuegt;lt;/propertygt;       lt;/beangt;             lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;!--  DataSource where objects will be persisted  --gt;       lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;bean id=quot;dataSourcequot; class=quot;org..jdbc.datasource.DriverManagerDataSourcequot;gt;lt;property name=quot;usernamequot; value=quot;${datasource.username}quot; /gt;lt;property name=quot;passwordquot; value=quot;${datasource.password}quot; /gt;lt;property name=quot;uclquot; value=quot;${datasource.ucl}quot; /gt;lt;property name=quot;driverClassNamequot; value=quot;${datasource.driver}quot; /gt;       lt;/beangt;             lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;!-- Factory bean for Hibernate Sessions --gt;       lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;bean id=quot;hibernateSessionFactoryquot; class=quot;org..orm.hibernate3.annotation.AnnotationSessionFactoryBeanquot;gt;lt;property name=quot;dataSourcequot; ref=quot;dataSourcequot; /gt;lt;property name=quot;annotatedClassesquot;gt;    lt;listgt;        lt;valuegt;gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvglt;/valuegt;    lt;/listgt;lt;/propertygt;lt;property name=quot;hibernatePropertiesquot;gt;    lt;propsgt;        lt;prop key=quot;hibernate.dialectquot;gt;${hibernate.dialect}lt;/propgt;        lt;prop key=quot;hibernate.hbm2ddl.autoquot;gt;${hibernate.hbm2ddlauto}lt;/propgt;    lt;/propsgt;lt;/propertygt;       lt;/beangt;             lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;!--  Transaction Manager bean  --gt;       lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;bean id=quot;transactionManagerquot; class=quot;org..orm.hibernate3.HibernateTransactionManagerquot;gt;lt;property name=quot;sessionFactoryquot; ref=quot;hibernateSessionFactoryquot; /gt;       lt;/beangt;             lt;tx:annotation-driven transaction-manager=quot;transactionManagerquot; /gt;             lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;!--  DAO for ESRL daily average objects  --gt;       lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --gt;       lt;bean id=quot;esrlDailyAvgDaoquot; class=quot;gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlDailyAvgDaoHibernateImplquot;gt;lt;property name=quot;sessionFactoryquot; ref=quot;hibernateSessionFactoryquot; /gt;lt;property name=quot;persistentClassquot; value=quot;gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvgquot; /gt;       lt;/beangt;         lt;/beansgt;
The generic DAO class (from which the DAO being used in my program is extended) looks like this:Code:      public class GenericDaoHibernateImpllt;T extends PersistentEntityltKgt;, PK extends Serializablegt;       implements GenericDaolt;T, PKgt;   {       private SessionFactory sessionFactory;          private Classlt;Tgt; persistentClass;          protected String getCanonicalPersistentClassName()       {return persistentClass.getCanonicalName();       }          /**        * Gets the current Hibernate Session object.        *         * @return        */       protected Session getCurrentSession()       {return sessionFactory.getCurrentSession();       }          /*        * (non-Javadoc)        * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#delete(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)        */       @Override       public void delete(final T persistentObject)       {getCurrentSession().delete(persistentObject);       }          /*        * (non-Javadoc)        * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#findAll()        */       @Override       public Listlt;Tgt; findAll()       {return getCurrentSession().createQuery(quot;from quot; + persistentClass.getName()).list();       }          /*        * (non-Javadoc)        * @see com.sun.cloud.lifecycle.core.persistence.dao.GenericDao#findById(java.io.Serializable)        */       @Override       public T findById(final PK id)       {return (T) getCurrentSession().load(persistentClass, id);       }          /*        * (non-Javadoc)        * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#saveOrUpdate(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)        */       @Override       public T saveOrUpdate(final T entity)       {try{    entity.setUpdatedDate(new Date());    getCurrentSession().saveOrUpdate(entity);    return entity;}catch (Exception ex){    String errorMessage = quot;Failed to save the object.quot;;    log.error(errorMessage, ex);    throw new RuntimeException(errorMessage, ex);}       }          /**        * Setter for the persistentClass property.        *         * @param persistentClass        */       public void setPersistentClass(final Classlt;Tgt; persistentClass)       {this.persistentClass = persistentClass;       }          /**        * Property setter.        *         * @param sessionFactory        */       public void setSessionFactory(final SessionFactory sessionFactory)       {this.sessionFactory = sessionFactory;       }      }
My application gets the DAO from the application context:

Code:   // load the Spring application context, get the DAOs   ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { quot;dailyAveragingApplicationContext.xmlquot; });   esrlDailyAvgDao = (EsrlDailyAvgDao) applicationContext.getBean(quot;esrlDailyAvgDaoquot;);   esrlObservationsDao = (EsrlObservationsDao) applicationContext.getBean(quot;esrlObservationsDaoquot;);
And the exception is encountered when I try to save an entity:Code:   esrlDailyAvgDao.saveOrUpdate(esrlDailyAvg);
The DAO class itself uses the Transactional annotation:

Code:      @Transactional   public class EsrlDailyAvgDaoHibernateImpl       extends GenericDaoHibernateImpllt;EsrlDailyAvg, Longgt;       implements EsrlDailyAvgDao
The exception stack trace looks like this:

Code:   SEVERE: Failed to save the object.   org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here   at org..orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)   at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)   at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)   at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)   at java.lang.reflect.Method.invoke(Unknown Source)   at org..aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)   at org..aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)   at $Proxy19.saveOrUpdate(Unknown Source)   at gov.noaa.ncdc.cmb.esrl.ingest.EsrlDailyAvgProcessor.main(EsrlDailyAvgProcessor.java:469)
Can anyone suggest where I've gone wrong?  Thanks in advance for your help.

--James

Maybe you should better extend your GenericDao from Spring's HibernateDaoSupport class. By using the helper methods like getHibernateTemplate().merge(entity)  Spring does all the overhead like opening and closing the session.

I resolved this by adding @Transactional to the base/generic Hibernate DAO implementation class (the parent class which implements the saveOrUpdate() method inherited by the DAO I use in the main program), i.e. the @Transactional needs to be specified on the actual class which implements the method. My assumption was instead that if I declared @Transactional on the child class then it included all of the methods that were inherited by the child class. However it seems that the @Transactional annotation only applies to methods implemented within a class and not to methods inherited by a class.
¥
Back Forum Reply New