Spring JPA没有正在进行的事务

我是Spring和JPA的新手,浪费了5天,搜索互联网没有结果。 我想将对象保存到SQL SERVER,连接是正确的,但是当我写.flush()时,我得到了exception

嵌套exception是javax.persistence.TransactionRequiredException:没有事务正在进行中

这是我的jpaContext.xml

                true create org.hibernate.dialect.SQLServerDialect               

这是我的persistence.xml文件:

    com.misha.model.Table1   

这是我的服务实现:

 @Service("manService") public class SaveManImpl implements SaveMan { // @Autowired private ManRepositoryImpl manRepo; @Transactional public Table1 save(Table1 table) { manRepo.save(table); return null; } } 

最后我的Repository实现:

 @Repository("manRepository") public class ManRepositoryImpl implements ManRepository { @PersistenceContext private EntityManager em; public Table1 save(Table1 table){ em.persist(table); em.flush(); return table; } } 

从例外情况来看,Spring看不到@Transactional注释,对吗? 我试着把注释放在上面的存储库保存方法,没有结果,经过上面的Service保存方法,这里也一样。 提前致谢

在此处输入图像描述

我在Controller中调用了save方法

  package com.misha.controllers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestMapping; import com.misha.model.Table1; import com.misha.service.SaveMan; @Controller public class ManController { @Autowired SaveMan saveMan; // this is service interface @RequestMapping(value="/test1") public String saveMan(){ Table1 tab = new Table1(); tab.setName("name"); saveMan.save(tab); return "saveMan"; } } 

错误堆栈:

 SEVERE: Servlet.service() for servlet [fitTrackerServlet] in context with path [/test] threw exception [Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress] with root cause javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) at com.sun.proxy.$Proxy20.flush(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) at com.sun.proxy.$Proxy20.flush(Unknown Source) at com.misha.repository.ManRepositoryImpl.save(ManRepositoryImpl.java:21) at com.misha.service.SaveManImpl.save(SaveManImpl.java:19) at com.misha.controllers.ManController.saveMan(ManController.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:774) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549) at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source) 

Spring配置文件

    <!--  -->                              

你有两个Spring上下文:

  1. 主要的一个,由jpaContext.xml配置,其中来自服务和存储库包的bean被扫描,并由事务拦截器代理。

  2. mvc one,由另一个xml文件(你没有命名)配置,其作用是描述应用程序的MVC部分,即定义和配置例如控制器bean,视图解析器等。这个上下文是一个主要的孩子。

问题是您还要扫描此子上下文中的服务和存储库包。 因此,您最终得到了每个服务和存储库的两个实例:

  • 一个在主要上下文中,这是事务性的
  • 一个在子上下文中,而不是(因为子上下文不关心事务管理)

因此,控制器注入来自与控制器相同的上下文的服务:非事务性的服务。

要确认这一点,您可以在bean的构造函数中添加跟踪,并查看它们实例化的次数。

为了避免这个问题,有两种解决方案:

  • 避免在mvc上下文中扫描存储库和服务包:此上下文应该只关心与mvc相关的bean。 当Spring在控制器中注入服务时,它将不会在mvc上下文中找到服务,因此查找它,并在主上下文中找到它。 因此将注入交易服务。
  • 使用单个上下文:servlet之一,其中将定义应用程序中的所有bean。

您应该将您的实体管理器介绍给您的事务管理器,这样当您使用@Transactional注释您的函数时,它会从池中加载实例

     

HTH!

@Transactional故事,请尝试在方法的最开头添加@Transactional 。 这是我的问题。