Spring + Hibernate annotations: Pas de Session Hibernate lié à fil

Je suis nouveau sur le Printemps et j'ai essayé de créer une webapp avec la pile suivante:
Apache Tomcat 7, MySQL, Spring MVC, Hibernate 3, avec les annotations JPA.

Je suis en train d'apprendre en suivant le livre "le Printemps en Action, Troisième Édition" par Craig Murs.

Tout d'abord, j'ai voulu créer une page qui affiche des entrées j'ai ajouté manuellement à ma DB, mais il semble que mon application n'est pas capable de la création/récupération de toute la Session Hibernate de mon SessionFactory. Voici ma cause trace de la pile:

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)

Et voici mes Classes concernées/fichiers de configuration:

Mon HibernateDAO:

@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<Contact> listContact() {
@SuppressWarnings("unchecked")
List<Contact> 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);
}
}
}

Ma classe Contact:

@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
}

Ma classe de Contrôleur:

@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<String,Object> model){
model.put("contacts", contactDAO.listContact());
return "index";
}
}

Voici mon Contexte de Données de fichier de Config:

<bean id="DBpropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/jdbc.properties" />
</bean>
<bean id="dataSource" 
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/nbarraille" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.nbarraille.www.core" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- 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 -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

Voici mon Répartiteur Servlet config:

<mvc:resources mapping="/resources/**"
location="/resources/" />
<mvc:annotation-driven />
<context:component-scan base-package="com.nbarraille.www" />
<bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" />
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-def.xml</value>
</list>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>

Et enfin, voici mon web.xml fichier:

<servlet>
<servlet-name>nbarraille</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>nbarraille</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/nbarraille-service.xml
/WEB-INF/nbarraille-data.xml
/WEB-INF/nbarraille-security.xml
</param-value>
</context-param>

OriginalL'auteur nbarraille | 2011-02-25