Java-Spring,Hibernate:没有绑定到线程的会话
我尝试使用Spring、rest和Hibernate创建一个小示例。为了在编组完成时打开会话,我在web.xml中添加了过滤器org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 然而,现在我陷入了困境,这可能是因为我对AOP非常陌生。我面临的问题是,当发送请求时,会话未打开:Java-Spring,Hibernate:没有绑定到线程的会话,hibernate,spring,Hibernate,Spring,我尝试使用Spring、rest和Hibernate创建一个小示例。为了在编组完成时打开会话,我在web.xml中添加了过滤器org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 然而,现在我陷入了困境,这可能是因为我对AOP非常陌生。我面临的问题是,当发送请求时,会话未打开: 20.10.2011 17:26:40 org.apache.catalina.core.StandardWrapperValve invo
20.10.2011 17:26:40 org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet mvc-dispatcher threw exception
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:685)
我认为这与中描述的问题相同,但我无法让它工作
web.xml:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<filter>
<filter-name>SessionPerRequest</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionPerRequest</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Rest控制器,但尚未调用它。因此,不调用函数开头的断点
package de.company.springtest.controller;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import de.company.springtest.Item;
import de.company.springtest.Order;
@Controller
@RequestMapping("/user")
// localhost:8080/RESTfulTest/rest/user/abc
public class JSONController {
@Autowired
private SessionFactory sessionFactory;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
Order postOrderInJSON() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Order order = new Order();
order.getItems().add(new Item());
session.save(order);
// session.flush();
transaction.commit();
// session.close();
return order;
}
@RequestMapping(value = "get/{id}", method = RequestMethod.GET)
public @ResponseBody
Order getUserInJSON(/* @PathVariable Long id */) {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Order order = new Order();
order.getItems().add(new Item());
session.save(order);
// session.flush();
transaction.commit();
// session.close();
return order;
}
}
HibernateConfiguration.java
package de.company.springtest;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.dialect.MySQLDialect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
@Configuration
public class HibernateConfiguration {
@Value("#{dataSource}")
private DataSource dataSource;
@Bean
public AnnotationSessionFactoryBean sessionFactoryBean() {
Properties props = new Properties();
props.put("hibernate.dialect", MySQLDialect.class.getName());
props.put("hibernate.current_session_context_class", "thread");
props.put("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
props.put("hibernate.format_sql", "true");
AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
bean.setAnnotatedClasses(new Class[]{Item.class, Order.class});
bean.setHibernateProperties(props);
bean.setDataSource(this.dataSource);
bean.setSchemaUpdate(true);
return bean;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager( sessionFactoryBean().getObject() );
return hibernateTransactionManager;
}
}
您有什么建议我可以继续搜索吗?取消注释部件时的错误很可能是由于类路径中缺少aspectj造成的 或者,您可以在DAO中使用@Transactional注释,或者在应用程序设计中适合开始/结束事务的任何地方使用@Transactional注释,正如链接线程中的第一条注释所指出的那样。要启动事务(或手动执行),您需要使用这两种方法之一——仅配置事务管理器是不够的 嵌套异常是java.lang.NoClassDefFoundError:org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException 您需要将aspectJ(aspectjweaver.jar)与应用程序一起部署 如果您使用maven,请将其添加到pom中:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.9</version>
</dependency>
org.aspectj
aspectjweaver
1.6.9
org.aspectj
aspectjrt
1.6.9
如果您不使用maven,则可以手动添加这两个罐子。您的整个配置/接线看起来非常“原始”。此异常的原因=>您的“服务层”没有事务处理,因此Hibernate会抱怨 不要将@Transactional放在DAO级别上,因为有人建议=>这是错误的。您应该始终在服务层中的业务单元=>上进行事务处理 看看将Spring和Hibernate集成在一起的(只需克隆它) 实际上,有一个例子说明了这个异常的原因 以下是通过Spring AOP对正确的TX配置的详细说明:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<aop:config>
<aop:pointcut id="moneyMakingBusinessServiceMethods"
expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>
<aop:advisor advice-ref="moneyMakingAdvice"
pointcut-ref="moneyMakingBusinessServiceMethods"/>
</aop:config>
<tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="makeMoney" propagation="REQUIRED"/>
<tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.9</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<aop:config>
<aop:pointcut id="moneyMakingBusinessServiceMethods"
expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>
<aop:advisor advice-ref="moneyMakingAdvice"
pointcut-ref="moneyMakingBusinessServiceMethods"/>
</aop:config>
<tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="makeMoney" propagation="REQUIRED"/>
<tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>