title: Spring + Hibernate with annotations: No Hibernate Session bound to thread
body: <p>I'm new to Spring and I was trying to create a webapp with the following stack:
  Apache Tomcat 7, MySQL, Spring MVC, Hibernate 3 with JPA annotations.</p>
  
  <p>I am trying to learn by following the book "Spring in Action, Third Edition" by Craig Walls.</p>
  
  <p>First, I wanted to create a page that displays some entries I manually added to my DB, but it looks like my application is not capable of creating/retrieving any Hibernate Session from my SessionFactory. Here is my root cause stack trace:</p>
  
  <pre><code>exception
  
  org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
  
  root cause
  
  org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
      org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
      org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
      com.nbarraille.www.dao.HibernateContactDAO.listContact(HibernateContactDAO.java:27)
      com.nbarraille.www.controllers.HomeController.showHomePage(HomeController.java:24)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      java.lang.reflect.Method.invoke(Method.java:613)
      org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
      org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
      org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
  </code></pre>
  
  <p>And here are my concerned Classes/Config files:</p>
  
  <p>My HibernateDAO:</p>
  
  <pre><code>@Repository
  public class HibernateContactDAO implements ContactDAO {
  
      private SessionFactory sessionFactory;
  
      @Autowired
      public HibernateContactDAO(SessionFactory sessionFactory){
          this.sessionFactory = sessionFactory;
      }
  
      public void addContact(Contact contact) {
          sessionFactory.getCurrentSession().save(contact);
      }
  
      public List&lt;Contact&gt; listContact() {
          @SuppressWarnings("unchecked")
          List&lt;Contact&gt; cl = sessionFactory.getCurrentSession().createQuery("from Contact").list();
          return cl;
      }
  
      public void removeContact(Integer id) {
          Contact contact = (Contact) sessionFactory.getCurrentSession().load(Contact.class, id);
          if (null != contact) {
              sessionFactory.getCurrentSession().delete(contact);
          }
  
      }
  }
  </code></pre>
  
  <p>My Contact class:</p>
  
  <pre><code>@Entity
  @Table(name="contacts")
  public class Contact implements Serializable {
      private static final long serialVersionUID = -5389913432051078273L;
  
      @Id
      @Column(name="id")
      @GeneratedValue
      private int id;
  
      @Column(name="first_name")
      private String firstname;
  
      @Column(name="last_name")
      private String lastname;
  
      @Column(name="email")
      private String email;
  
      @Column(name="telephone")
      private String telephone;
  
  
      // Setters/Getters
  }
  </code></pre>
  
  <p>My Controller class:</p>
  
  <pre><code>@Controller
  
      public class HomeController {
  
          private ContactDAO contactDAO; // I know I should pass through a service instead of accessing my DAO directly, and I usually do, but I skipped it here to simplify and try to locate the problem
  
          @Inject
          public HomeController(ContactDAO contactDAO){
              this.contactDAO = contactDAO;
          }
  
          @RequestMapping({"/", "/home"})
          public String showHomePage(Map&lt;String,Object&gt; model){
              model.put("contacts", contactDAO.listContact());
              return "index";
          }
      }
  </code></pre>
  
  <p>Here is my Context Data Config file:</p>
  
  <pre><code>&lt;bean id="DBpropertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
      &lt;property name="location" value="/WEB-INF/jdbc.properties" /&gt;
      &lt;/bean&gt;
  
  &lt;bean id="dataSource" 
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
      &lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
      &lt;property name="url" value="jdbc:mysql://localhost:3306/nbarraille" /&gt;
      &lt;property name="username" value="root" /&gt;
      &lt;property name="password" value="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="packagesToScan" value="com.nbarraille.www.core" /&gt;
          &lt;property name="hibernateProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;
                  &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;!-- Adds an advisor to any bean annotated with @Repository so that any platform-specific exception
           are caught and then rethrown as one of Spring's unchecked data access exceptions --&gt;
      &lt;bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /&gt;
  </code></pre>
  
  <p>Here is my Dispatcher Servlet config:</p>
  
  <pre><code>&lt;mvc:resources mapping="/resources/**"
                     location="/resources/" /&gt;
  
  &lt;mvc:annotation-driven /&gt;
  
  &lt;context:component-scan base-package="com.nbarraille.www" /&gt;
  
  &lt;bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" /&gt;
  
  &lt;bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"&gt;
          &lt;property name="definitions"&gt;
              &lt;list&gt;
                  &lt;value&gt;/WEB-INF/tiles-def.xml&lt;/value&gt;
              &lt;/list&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="messageSource"
          class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&gt;
          &lt;property name="basename" value="classpath:messages" /&gt;
          &lt;property name="defaultEncoding" value="UTF-8"/&gt;
      &lt;/bean&gt;
  
      &lt;bean id="localeChangeInterceptor"
          class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"&gt;
          &lt;property name="paramName" value="lang" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="localeResolver"
          class="org.springframework.web.servlet.i18n.CookieLocaleResolver"&gt;
          &lt;property name="defaultLocale" value="en"/&gt;
      &lt;/bean&gt;
  </code></pre>
  
  <p>And finally, here is my web.xml file:</p>
  
  <pre><code>&lt;servlet&gt;
      &lt;servlet-name&gt;nbarraille&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;nbarraille&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;
  
   &lt;context-param&gt;
      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
      &lt;param-value&gt;
          /WEB-INF/nbarraille-service.xml
          /WEB-INF/nbarraille-data.xml
          /WEB-INF/nbarraille-security.xml
      &lt;/param-value&gt;
  &lt;/context-param&gt;
  </code></pre>