I am working on a Spring MVC project. I use Hibernate directly. No Session found for current thread error occurred in my project. I know that on stackoverflow and elsewhere on the Internet this error is very common. But I did not find a working solution for my problem.
I had an unresolved issue with the correct configuration of the Hibernate Factory session. I described it here: Is it possible to use a Hibernate Factory session declared in the DispatcherServlet context instead of hibernate.cfg.xml? But finally, I use the hibernate.cfg.xml file and also the Hibernate Factory session defined in the DispatcherServlet context file. I did some simple operations, such as persistent classes in a database. And everything was in order.
At the moment, my project has much in common with Spring MVC Hibernate . I added some annotations to my classes, and I created some new service classes.
The My ServletDispatcher context file contains the following definitions:
<annotation-driven /> <context:annotation-config /> <context:component-scan base-package="finances.webapp" /> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /> <beans:property name="url" value="jdbc:mysql://localhost/finances" /> <beans:property name="username" value="root" /> <beans:property name="password" value="root" /> </beans:bean> <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <beans:property name="dataSource"> <beans:ref bean="dataSource" /> </beans:property> <beans:property name="configLocation" value="classpath:hibernate.cfg.xml" /> </beans:bean> <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <beans:property name="sessionFactory" ref="sessionFactory" /> </beans:bean> <beans:bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <beans:property name="transactionManager" ref="transactionManager" /> <beans:property name="transactionAttributes"> <beans:props> <beans:prop key="save">PROPAGATION_REQUIRED</beans:prop> </beans:props> </beans:property> </beans:bean>
In my pom.xml file, I have only these two dependencies according to ORM:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.1.4.Final</version> </dependency> <dependency> <groupId>javax.ejb</groupId> <artifactId>ejb-api</artifactId> <version>3.0</version> <scope>provided</scope> </dependency>
Maybe the problem is here? But before, I had no problems with missing packages.
This is my controller code:
UsersEntity user2 = new UsersEntity("qwerty", "qwerty", true); usersService.addUser(user2);
The No Session found for current thread problem occurred while calling the addUser() method.
My DAO class:
@Repository public class UsersHome { @Autowired private SessionFactory sessionFactory; public void persist(UsersEntity transientInstance) { sessionFactory.getCurrentSession().persist(transientInstance); } }
My service:
@Service public class UsersService { @Autowired private UsersHome usersHome; @Transactional(propagation = Propagation.REQUIRED) public void addUser(UsersEntity user) { usersHome.persist(user); } }
This code stops working when I have the body of the change method in the UsersHome class. I used to start a session before my action and end the session after my action. But using annotations and transactions, should it work? Please give me some advice.
EDIT
<hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <property name="connection.url">jdbc:mysql://localhost/finances</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <mapping class="finances.webapp.entities.AuthoritiesEntity"/> <mapping class="finances.webapp.entities.ExpensesEntity"/> <mapping class="finances.webapp.entities.ExpensesCategoriesEntity"/> <mapping class="finances.webapp.entities.ExpensesObjectsEntity"/> <mapping class="finances.webapp.entities.IncomesEntity"/> <mapping class="finances.webapp.entities.UsersEntity"/> </session-factory> </hibernate-configuration>
EDIT No. 2
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usersService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private finances.webapp.dao.UsersHome finances.webapp.services.UsersService.usersHome; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usersHome': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory finances.webapp.dao.UsersHome.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/hibernate/cfg/EJB3DTDEntityResolver
EDIT No. 3
My root-context.xml file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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-3.0.xsd"> </beans>
And my whole spring-config.xml file:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <annotation-driven /> <context:annotation-config /> <context:component-scan base-package="finances.webapp" /> <resources mapping="/resources/**" location="/resources/" /> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /> <beans:property name="url" value="jdbc:mysql://localhost/finances" /> <beans:property name="username" value="root" /> <beans:property name="password" value="root" /> </beans:bean> <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <beans:property name="dataSource" ref="dataSource" /> <beans:property name="configLocation" value="classpath:hibernate.cfg.xml" /> </beans:bean> <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <beans:property name="sessionFactory" ref="sessionFactory" /> </beans:bean> <beans:bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <beans:property name="transactionManager" ref="transactionManager" /> <beans:property name="transactionAttributes"> <beans:props> <beans:prop key="save">PROPAGATION_REQUIRED</beans:prop> <beans:prop key="persist">PROPAGATION_REQUIRED</beans:prop> </beans:props> </beans:property> </beans:bean> </beans:beans>