title: Problem with transactions: No Hibernate Session bound to thread
body: <p>I refactored my service layer to work as generic component. After that all request to my controller began to throw org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here.</p>
  
  <p>I searched over the internet and found common reasons:</p>
  
  <ol>
  <li>Lack of @Transaction annotation. </li>
  <li>Usage of hibernate.current_session_context_class and hibernate.transaction_factory_class options. </li>
  <li>Direct calls to sessionFactory.openSession(). </li>
  <li>Using BeanFactory instead of ApplicationContext.</li>
  <li>Several instances of DAO class. </li>
  </ol>
  
  <p>But it seems that none of them are related to my case.</p>
  
  <p>I would appreciate any help as I've spent all my day with this exception.</p>
  
  <p><strong>Stacktrace</strong></p>
  
  <pre><code>[INFO] 2011-08-12 15:42:49,383 [btpool0-0] INFO  ru.centr_in.rescuer.server.web.InfoJournalController - FETCH started: all
  [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils - Opening Hibernate Session
  [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13131493693
  [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils - Closing Hibernate Session
  [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
  [INFO] org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  [INFO]  at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
  [INFO]  at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574)
  [INFO]  at ru.centr_in.rescuer.server.dao.HibernateGenericDao.findAll(HibernateGenericDao.java:41)
  [INFO]  at ru.centr_in.rescuer.server.service.AbstractCRUDServiceBean.findAll(AbstractCRUDServiceBean.java:21)
  [INFO]  at ru.centr_in.rescuer.server.web.InfoJournalController.getInfoJournalEntries(InfoJournalController.java:40)
  [INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  [INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  [INFO]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  [INFO]  at java.lang.reflect.Method.invoke(Method.java:597)
  [INFO]  at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
  [INFO]  at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
  [INFO]  at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
  [INFO]  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
  [INFO]  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
  [INFO]  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
  [INFO]  at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
  [INFO]  at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
  [INFO]  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  [INFO]  at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
  [INFO]  at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
  [INFO]  at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
  [INFO]  at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
  [INFO]  at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
  [INFO]  at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
  [INFO]  at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
  [INFO]  at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
  [INFO]  at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
  [INFO]  at org.mortbay.jetty.Server.handle(Server.java:324)
  [INFO]  at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
  [INFO]  at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829)
  [INFO]  at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
  [INFO]  at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
  [INFO]  at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
  [INFO]  at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
  [INFO]  at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
  </code></pre>
  
  <p><strong>Controller</strong></p>
  
  <pre><code>@Controller
  public class InfoJournalController {
  
      @Autowired
      private InfoJournalService infoJournalService;
  
      @RequestMapping(value="/infoJournal", method=RequestMethod.GET)
      public @ResponseBody InfoJournalEntry[] getInfoJournalEntries() {
  
          List&lt;InfoJournalEntry&gt; entries = infoJournalService.findAll();
          InfoJournalEntry[] result = new InfoJournalEntry[entries.size()];
          entries.toArray(result);
          return result;
      }
  } 
  </code></pre>
  
  <p><strong>Generic service interface</strong></p>
  
  <pre><code>public interface AbstractCRUDService&lt;E, PK extends Serializable&gt; {
      void save(E entity);
      List&lt;E&gt; findAll();
      E findById(PK id);
      void delete(E entity);
      void update(E entity);
  } 
  </code></pre>
  
  <p><strong>Generic service implementation</strong></p>
  
  <pre><code>@Transactional
  public abstract class AbstractCRUDServiceBean&lt;E, PK extends Serializable&gt; implements   AbstractCRUDService&lt;E, PK&gt; {
  
      //....
  
      @Transactional
      public List&lt;E&gt; findAll() {
          return getDao().findAll();
      }
  
      //....
  
      public abstract AbstractDao&lt;E, PK&gt; getDao();
  }
  </code></pre>
  
  <p><strong>Concrete service interface</strong></p>
  
  <pre><code>public interface InfoJournalService extends AbstractCRUDService&lt;InfoJournalEntry, Long&gt;     }
  </code></pre>
  
  <p><strong>Concrete service implementation</strong></p>
  
  <pre><code>@Service("infoJournalService")
  public class InfoJournalServiceImpl extends AbstractCRUDServiceBean&lt;InfoJournalEntry, Long&gt; implements InfoJournalService {
  
      @Autowired
      private InfoJournalDao infoJournalDao;
  
      @Override
      public AbstractDao&lt;InfoJournalEntry, Long&gt; getDao() {
          return infoJournalDao;
      }
  }
  </code></pre>
  
  <p><strong>Generic DAO interface</strong></p>
  
  <pre><code>public abstract class HibernateGenericDao&lt;E, PK extends Serializable&gt; implements AbstractDao&lt;E, PK&gt; {
  
      @Autowired
      protected SessionFactory sessionFactory;
  
      //....
  
      @SuppressWarnings("unchecked")
      public List&lt;E&gt; findAll() {
          return sessionFactory.getCurrentSession().createCriteria(getEntityClass()).list();
      }
  
      public abstract Class getEntityClass();
  }
  </code></pre>
  
  <p><strong>Generic DAO implementation</strong>
      public abstract class HibernateGenericDao implements AbstractDao {</p>
  
  <pre><code>    @Autowired
      protected SessionFactory sessionFactory;
  
      //....
  
      @SuppressWarnings("unchecked")
      public List&lt;E&gt; findAll() {
          return sessionFactory.getCurrentSession().createCriteria(getEntityClass()).list();
      }
  
      public abstract Class getEntityClass();
  }
  </code></pre>
  
  <p><strong>Concrete DAO implementation</strong></p>
  
  <pre><code>@Repository("infoJournalDao")
  public class InfoJournalDaoImpl extends HibernateGenericDao&lt;InfoJournalEntry, Long&gt;     implements InfoJournalDao {
  
      @Override
      public Class getEntityClass() {
          return InfoJournalEntry.class;
      }
  }
  </code></pre>
  
  <p><strong>root-context.xml</strong></p>
  
  <pre><code>  &lt;context:annotation-config /&gt;
    &lt;context:component-scan base-package="ru.centr_in.rescuer.server" /&gt;
    &lt;import resource="datasource.xml" /&gt;
  </code></pre>
  
  <p><strong>datasource.xml</strong></p>
  
  <pre><code> &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" &gt;
    &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
   &lt;/bean&gt;
  
   &lt;tx:annotation-driven transaction-manager="transactionManager"/&gt;  
  
   &lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
    &lt;property name="location"&gt;
      &lt;value&gt;WEB-INF/database.properties&lt;/value&gt;
    &lt;/property&gt;
   &lt;/bean&gt;
  
   &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
    &lt;property name="driverClassName" value="${jdbc.driverClassName}" /&gt;
    &lt;property name="url" value="${jdbc.url}"/&gt;
    &lt;property name="username" value="${jdbc.username}"/&gt;
    &lt;property name="password" value="${jdbc.password}"/&gt;
   &lt;/bean&gt;
  
   &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt;
     &lt;property name="dataSource" ref="dataSource"/&gt;
     &lt;property name="configurationClass"&gt;
       &lt;value&gt;org.hibernate.cfg.AnnotationConfiguration&lt;/value&gt;
     &lt;/property&gt;
     &lt;property name="hibernateProperties"&gt;
       &lt;props&gt;
         &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;
         &lt;prop key="hibernate.hbm2ddl.auto"&gt;create&lt;/prop&gt; 
         &lt;prop key="hibernate.dialect"&gt;${jdbc.dialect}&lt;/prop&gt;
         &lt;prop key="hibernate.connection.charset"&gt;UTF-8&lt;/prop&gt;
       &lt;/props&gt;
     &lt;/property&gt;
  
     &lt;property name="annotatedClasses"&gt;
          &lt;list&gt;
              &lt;value&gt;ru.centr_in.rescuer.server.domain.InfoJournalEntry&lt;/value&gt;
          &lt;/list&gt;
     &lt;/property&gt;
   &lt;/bean&gt;
  </code></pre>
  
  <p><strong>servlet-context.xml</strong></p>
  
  <pre><code> &lt;annotation-driven/&gt;
   &lt;context:component-scan base-package="ru.centr_in.rescuer.server" /&gt;
  
   &lt;resources mapping="/resources/**" location="/resources/"/&gt;
   &lt;resources mapping="/Rescuer.html" location="/Rescuer.html"/&gt;
   &lt;resources mapping="/Rescuer/**" location="/Rescuer/"/&gt;
  
   &lt;beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
      &lt;beans:property name="prefix" value="/WEB-INF/views/"/&gt;
      &lt;beans:property name="suffix" value=".jsp"/&gt;
   &lt;/beans:bean&gt;
  </code></pre>