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
Vous devez vous connecter pour publier un commentaire.
Vous ne semblez pas avoir de transaction configuré encore... vous pouvez ajouter la ligne suivante dans votre Données de Contexte Config fichier:-
Changement VOTRE.PACKAGE votre véritable nom du paquet, par exemple:-
C'est une manière paresseuse pour l'emballage de tous vos méthodes dans votre projet avec des de transactions.
Par ailleurs, si vous allez paresseusement les requêtes Hibernate objets du domaine (ex:
parent.getChildren()
) à votre avis, alors je vous suggère fortement d'ajouter ceci dans votre web.xml:-Ce filtre s'étend session Hibernate pour la vue.
@Transactional
notation sur votre DAO comme une alternative à l'aop.L'ajout du filtre chose me débarrasser de cette erreur, merci. Qu'est-ce que c'est exactement? Je n'ai pas d'ajouter le support de transaction pourtant, comme je ne sais pas ce que c'est.
Ce filtre assure votre point de vue de la couche a accès à la session Hibernate. Gardez à l'esprit, vous aurez besoin de ce filtre ET la transaction est configuré si vous voulez vos trucs pour fonctionner correctement. Avoir ce filtre ne signifie pas que vous avez des trasaction enroulée sur chaque demande de l'utilisateur. Lire ceci pour plus d'info: static.springsource.org/spring/docs/1.2.9/api/org/...
OriginalL'auteur limc
Pour ce que ça vaut
... courir dans cette ainsi, après beaucoup de recherche avait pour modifier une partie de web.xml:
... , en particulier, ont pour définir singleSession à vrai
OriginalL'auteur vector
J'ai le même problème aujourd'hui. Il est connecté avec mise en veille prolongée de l'unité de travail de conception de base de données et des transactions. Si peu de temps de parole. Si vous utilisez le cadre du printemps, il dispose de son propre gestionnaire de transactions et de la session de l'usine impelementation. Mais si vous souhaitez l'utiliser, vous shuld n'oubliez pas de le configurer, mais aussi correcte de l'ordre de la adnotation. Votre service doit être @Transactional, votre DAO devrait être @Référentiel et DAO utiliser @Entity beans.
Donc si vous utilisez le printemps de la mise en œuvre de gestionnaire de transactions, vous devez utiliser votre transactionnelle service dans votre contrôleur 😉 c'est assez simple et dans votre dao vous ne sessionfactory.getCurrentSession() pour obtenir session 😉
OriginalL'auteur RMachnik