我有一个使用spring和hibernate的java stuts2 Web应用程序。
我越来越org.hibernate.HibernateException: No Session found for current thread。
org.hibernate.HibernateException: No Session found for current thread
SpringBean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <context:component-scan base-package="org.rohith" /> <context:annotation-config /> <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/company" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="mappingResources"> <list> <value>hibernate.cfg.xml</value> </list> </property> </bean> <!-- <tx:annotation-driven/> --> <bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /> </bean> <bean id="customerDaoImpl" class="org.rohith.dao.impl.CustomerDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="customerServiceImpl" class="org.rohith.service.impl.CustomerServiceImpl"> <property name="customerDaoImpl" ref="customerDaoImpl"/> </bean> </beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Names the annotated entity class --> <mapping class="org.rohith.model.Customer"/> </session-factory> </hibernate-configuration>
CustomerServiceImpl.java
package org.rohith.service.impl; import org.rohith.dao.impl.CustomerDaoImpl; import org.rohith.model.Customer; import org.rohith.service.CustomerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CustomerServiceImpl implements CustomerService { @Autowired private CustomerDaoImpl customerDaoImpl; @Override public void saveCustomer(Customer customer) { customerDaoImpl.saveCustomer(customer); } public CustomerDaoImpl getCustomerDaoImpl() { return customerDaoImpl; } public void setCustomerDaoImpl(CustomerDaoImpl customerDaoImpl) { this.customerDaoImpl = customerDaoImpl; } }
CustomerDaoImpl.java
package org.rohith.dao.impl; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.rohith.dao.CustomerDao; import org.rohith.model.Customer; public class CustomerDaoImpl implements CustomerDao { private SessionFactory sessionFactory; @Override public void saveCustomer(Customer customer) { Session session = getSession(); session.clear(); try { session.saveOrUpdate(customer); session.flush(); } catch (Throwable e) { throw new RuntimeException(e.getMessage(), e); } } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public SessionFactory getSessionFactory() { return this.sessionFactory; } public Session getSession() throws HibernateException { Session sess = getSessionFactory().getCurrentSession(); if (sess == null) { sess = getSessionFactory().openSession(); } // Session sess = getSessionFactory().openSession(); return sess; } }
CustomerAction.java
public class CustomerAction extends ActionSupport{ private String name; private String addr1; private String addr2; private String city; private String state; private CustomerServiceImpl customerServiceImpl; //Getters and setters public String execute(){ Customer cust= new Customer(); cust.setName(name); cust.setAddress1(addr1); cust.setAddress2(addr2); cust.setCity(city); cust.setState(state); System.out.println(name); WebApplicationContext webApplicationContext = WebApplicationContextUtils .getRequiredWebApplicationContext(getRequest().getSession() .getServletContext()); customerServiceImpl = (CustomerServiceImpl) webApplicationContext.getBean("customerServiceImpl"); customerServiceImpl.saveCustomer(cust); //saveCust(cust); return "success"; } protected HttpServletRequest getRequest() { return ServletActionContext.getRequest(); } protected HttpServletResponse getResponse() { return ServletActionContext.getResponse(); } }
我得到的例外
org.hibernate.HibernateException: No Session found for current thread org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:978) org.rohith.dao.impl.CustomerDaoImpl.getSession(CustomerDaoImpl.java:33) org.rohith.dao.impl.CustomerDaoImpl.saveCustomer(CustomerDaoImpl.java:16) org.rohith.service.impl.CustomerServiceImpl.saveCustomer(CustomerServiceImpl.java:18) org.rohith.CustomerAction.execute(CustomerAction.java:36) 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:606)
您在Spring配置中指定了一个事务管理器,但是没有关于何时或何处应用事务的配置。
在您的 SpringBean.xml中, 您应该取消注释<tx:annotation-driven/>:
<tx:annotation-driven/>
<tx:annotation-driven transaction-manager="transactionManager"/>
然后,您应该将CustomerServiceImpl.saveCustomer方法注释为@Transactional:
CustomerServiceImpl.saveCustomer
@Transactional
@Service public class CustomerServiceImpl implements CustomerService { ... @Override @Transactional public void saveCustomer(Customer customer) { customerDaoImpl.saveCustomer(customer); } ... }