Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

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 <tx:annotation-driven/> 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:

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.springframework.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) 

I have the following application context configuration file:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:aop="http://www.springframework.org/schema/aop"        xmlns:flex="http://www.springframework.org/schema/flex"        xmlns:tx="http://www.springframework.org/schema/tx"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans                            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd                            http://www.springframework.org/schema/flex                            http://www.springframework.org/schema/flex/spring-flex-1.0.xsd                            http://www.springframework.org/schema/tx                            http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">      <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  load values used for bean properties  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">         <property name="locations">             <value>applicationContext.properties</value>         </property>     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  DataSource where objects will be persisted  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">         <property name="username" value="${datasource.username}" />         <property name="password" value="${datasource.password}" />         <property name="url" value="${datasource.url}" />         <property name="driverClassName" value="${datasource.driver}" />     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!-- Factory bean for Hibernate Sessions -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">         <property name="dataSource" ref="dataSource" />         <property name="annotatedClasses">             <list>                 <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg</value>                 <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations</value>                 <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation</value>             </list>         </property>         <property name="hibernateProperties">             <props>                 <prop key="hibernate.dialect">${hibernate.dialect}</prop>                 <prop key="hibernate.show_sql">false</prop>                 <prop key="hibernate.format_sql">true</prop>                 <prop key="hibernate.use_sql_comments">true</prop>                 <prop key="hibernate.jdbc.batch_size">50</prop>                 <prop key="hibernate.query.substitutions">true 1, false 0</prop>                 <prop key="hibernate.max_fetch_depth">6</prop>                 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddlauto}</prop>                 <prop key="hibernate.cache.use_second_level_cache">${hibernate.use_second_level_cache}</prop>             </props>         </property>     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  Transaction Manager bean  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">         <property name="sessionFactory" ref="hibernateSessionFactory" />     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  enable the configuration of transactional behavior based on annotations  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <tx:annotation-driven transaction-manager="transactionManager" />       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  DAO for ESRL Station objects  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="esrlStationDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlStationDaoHibernateImpl">         <property name="sessionFactory" ref="hibernateSessionFactory" />         <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation" />     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  DAO for ESRL Observations objects  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="esrlObservationsDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlObservationsDaoHibernateImpl">         <property name="sessionFactory" ref="hibernateSessionFactory" />         <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations" />     </bean>       <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <!--  DAO for ESRL daily average objects  -->     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->     <bean id="esrlDailyAvgDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlDailyAvgDaoHibernateImpl">         <property name="sessionFactory" ref="hibernateSessionFactory" />         <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg" />     </bean>   </beans>  

The generic DAO class (from which the DAO being used in my program is extended) looks like this:

package gov.noaa.ncdc.cmb.persistence.dao;  import gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity; import java.io.Serializable; import java.util.Collection; import java.util.Date; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Example;  /**  * This class is an implementation of GenericDao<T, PK> using Hibernate.  */ public class GenericDaoHibernateImpl<T extends PersistentEntity<PK>, PK extends Serializable>     implements GenericDao<T, PK> {     private SessionFactory sessionFactory;      static private Log log = LogFactory.getLog(GenericDaoHibernateImpl.class);      private Class<T> persistentClass;      /**      * Can be used within subclasses as a convenience method.      *       * @param criterionList the criteria to find by      * @return the list of elements that match the specified criteria      */     protected List<T> findByCriteria(final List<Criterion> criterionList)     {         Criteria criteria = getCurrentSession().createCriteria(persistentClass);         for (Criterion criterion : criterionList)         {             criteria.add(criterion);         }         return criteria.list();     }      protected String getCanonicalPersistentClassName()     {         return persistentClass.getCanonicalName();     }      /**      * Gets the current Hibernate Session object.      *       * @return      */     protected Session getCurrentSession()     {         return sessionFactory.getCurrentSession();     }      /*      * This method only provided for interface compatibility.  Not recommended for use with large batches       * (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).      *       * (non-Javadoc)      * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchInsert(java.util.Collection)      */     @Override     public int[] batchInsert(final Collection<T> entityCollection)     {         int[] updateCounts = new int[entityCollection.size()];         int i = 0;         for (T entity : entityCollection)         {             try             {                 saveOrUpdate(entity);                 updateCounts[i] = 1;                 i++;             }             catch (Exception ex)             {                 clear();                 throw new RuntimeException(ex);             }         }         flush();         clear();          return updateCounts;     }      /*      * This method only provided for interface compatibility.  Not recommended for use with large batches       * (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).      *       * (non-Javadoc)      * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchUpdate(java.util.Collection)      */     @Override     public int[] batchUpdate(final Collection<T> entityCollection)     {         return batchInsert(entityCollection);     }      /**      * Completely clear the session. Evict all loaded instances and cancel all pending saves, updates and deletions. Do      * not close open iterators or instances of ScrollableResults.      */     public void clear()     {         getCurrentSession().clear();     }      /*      * (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 List<T> findAll()     {         return getCurrentSession().createQuery("from " + persistentClass.getName()).list();     }      /**      * Finds a collection of entity objects which match to the example instance, minus any specified properties which should be excluded from the matching.      *       * @param exampleInstance      * @param excludeProperty      * @return      */     public List<T> findByExample(final T exampleInstance,                                  final String[] excludeProperty)     {         Criteria criteria = getCurrentSession().createCriteria(persistentClass);         Example example = Example.create(exampleInstance);         if (excludeProperty != null)         {             for (String exclude : excludeProperty)             {                 example.excludeProperty(exclude);             }         }         criteria.add(example);         return criteria.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);     }      /**      * Force this session to flush. Must be called at the end of a unit of work, before commiting the transaction and      * closing the session (depending on flush-mode, Transaction.commit() calls this method).      *       * Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.      */     public void flush()     {         getCurrentSession().flush();     }      /*      * (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 = "Failed to save the object.";             log.error(errorMessage, ex);             throw new RuntimeException(errorMessage, ex);         }     }      /**      * Setter for the persistentClass property.      *       * @param persistentClass      */     public void setPersistentClass(final Class<T> 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:

// load the Spring application context, get the DAOs ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "dailyAveragingApplicationContext.xml" }); esrlDailyAvgDao = (EsrlDailyAvgDao) applicationContext.getBean("esrlDailyAvgDao"); esrlObservationsDao = (EsrlObservationsDao) applicationContext.getBean("esrlObservationsDao"); 

And the exception is encountered when I try to save an entity:

esrlDailyAvgDao.saveOrUpdate(esrlDailyAvg); 

The DAO class itself uses the Transactional annotation:

@Transactional public class EsrlDailyAvgDaoHibernateImpl     extends GenericDaoHibernateImpl<EsrlDailyAvg, Long>     implements EsrlDailyAvgDao 

The exception stack trace looks like this:

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.springframework.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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)     at $Proxy19.saveOrUpdate(Unknown Source)     at gov.noaa.ncdc.cmb.esrl.ingest.EsrlDailyAvgProcessor.main(EsrlDailyAvgProcessor.java:469) 
like image 390
James Adams Avatar asked Feb 10 '11 19:02

James Adams


People also ask

Is hibernate getCurrentSession thread safe?

Hibernate SessionFactory getCurrentSession Since this session object belongs to the hibernate context, we don't need to close it. Once the session factory is closed, this session object gets closed. Hibernate Session objects are not thread safe, so we should not use it in multi-threaded environment.

What is Current_session_context_class in hibernate?

hibernate. context. CurrentSessionContext ) and a new configuration parameter ( hibernate. current_session_context_class ) have been added to allow pluggability of the scope and context of defining current sessions.

What is SessionFactory in hibernate?

SessionFactory is an Interface which is present in org. hibernate package and it is used to create Session Object. It is immutable and thread-safe in nature. buildSessionFactory() method gathers the meta-data which is in the cfg Object.

Can you describe the different contextual sessions in hibernate?

For example: a single transaction could be such a context, hence if the Hibernate Session's lifecycle matches a life of this transaction, the Session could be called contextual, where a single transaction defines such a context . Sometimes this particular case is labeled as a session-per-request model.


2 Answers

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.

like image 196
James Adams Avatar answered Sep 26 '22 14:09

James Adams


I got the following error:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here     at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63) 

I fixed this by changing my hibernate properties file

hibernate.current_session_context_class=thread 

My code and configuration file as follows

session =  getHibernateTemplate().getSessionFactory().getCurrentSession();  session.beginTransaction();  session.createQuery(Qry).executeUpdate();  session.getTransaction().commit(); 

on properties file

hibernate.dialect=org.hibernate.dialect.MySQLDialect  hibernate.show_sql=true  hibernate.query_factory_class=org.hibernate.hql.ast.ASTQueryTranslatorFactory  hibernate.current_session_context_class=thread 

on cofiguration file

<properties> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>          <prop key="hibernate.query.factory_class">${hibernate.query_factory_class}</prop>        <prop key="hibernate.generate_statistics">true</prop> <prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop> </props> </property> </properties> 

Thanks,
Ashok

like image 45
Ashok Avatar answered Sep 22 '22 14:09

Ashok