Spring + Hibernate : No Session found for current thread
By:Roy.LiuLast updated:2019-08-17
Integrates Spring 3 and Hibernate 4, the system shows the following message while performing database operation :
org.hibernate.HibernateException: No Session found for current thread
The sessionFactory is injected like this :
spring-hibernate4.xml
<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"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>orm/Users.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQL5Dialect </value> </property> </bean> <bean id="userDao" class="com.mkyong.users.dao.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="userService" class="com.mkyong.users.service.UserServiceImpl"> <property name="userDao" ref="userDao" /> </bean> </beans>
Solution
The sessionFactory needs transaction to work, to solve it, declare a transaction manager in Spring.
Solution 1 : Declarative transaction management, declare transaction manager in an XML file, via Spring AOP.
spring-hibernate4.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>orm/Users.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQL5Dialect </value> </property> </bean> <bean id="userDao" class="com.mkyong.users.dao.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="userService" class="com.mkyong.users.service.UserServiceImpl"> <property name="userDao" ref="userDao" /> </bean> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="userServicePointCut" expression="execution(* com.mkyong.users.service.*Service.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointCut" /> </aop:config> </beans>
Solution 2 : Programmatic transaction management, declare transaction manager in code.
package com.mkyong.users.service; //... import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; public class UserServiceImpl implements UserService { private UserDao userDao; private TransactionTemplate transactionTemplate; public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionTemplate = new TransactionTemplate(transactionManager); @Override public UserDetails findByUsername(final String username) { // Programmatic transaction management return transactionTemplate.execute(new TransactionCallback<UserDetails>() { public UserDetails doInTransaction(TransactionStatus status) { UserDetails user = userDao.findByUserName(username); //etc etc });
Note
For more information, please visit this Official Spring Transaction Management.
For more information, please visit this Official Spring Transaction Management.
From:一号门
COMMENTS