Spring + Hibernate : No Session found for current thread

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.

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
0 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
0 Comment authors
Recent comment authors
newest oldest most voted