Spring JPA no hay transacción en curso

Soy nuevo en Spring y JPA, desperdicié 5 días y no obtuve ningún resultado con la búsqueda en Internet. Quiero guardar el objeto en SQL SERVER, la conexión es correcta, pero cuando escribo .flush () obtengo la excepción

la excepción anidada es javax.persistence.TransactionRequiredException: ninguna transacción está en progreso

Este es mi jpaContext.xml

                true create org.hibernate.dialect.SQLServerDialect               

Este es mi archivo persistence.xml:

    com.misha.model.Table1   

Esta es mi implementación del servicio:

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

Y finalmente la implementación de mi Repositorio:

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

De la excepción, Spring no puede ver la anotación @Transactional, ¿estoy en lo cierto? Intenté colocar la anotación sobre el método de guardado del repository, sin resultado, después de este método de guardado del Servicio anterior, el mismo aquí. Gracias por adelantado

enter image description here

Llamo al método guardar en mi controlador

  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"; } } 

Pila de errores:

 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) 

Archivo de configuración de spring

    <!--  -->                              

Tienes dos contextos de spring:

  1. la principal, configurada por jpaContext.xml, donde se escanean los beans de los paquetes de servicio y repository, y proxies por un interceptor transaccional.

  2. el mvc, configurado por el otro archivo xml (no lo nombró) cuya función es describir la parte MVC de la aplicación, es decir, definir y configurar, por ejemplo, los beans del controlador, el resolvedor de vistas, etc. Este contexto es un hijo del principal.

El problema es que también escanea los paquetes de servicio y repository en este contexto secundario. De este modo, termina con dos instancias de cada servicio y repository:

  • uno en el contexto principal, que es transaccional
  • uno en el contexto infantil, que no lo es (dado que el contexto infantil no se preocupa por la gestión de transacciones)

De este modo, al controlador se le inyecta un servicio que proviene del mismo contexto que el controlador: el no transaccional.

Para confirmarlo, puede agregar rastros en el constructor de los beans y ver cuántas veces se crean instancias.

Y para evitar el problema, hay dos soluciones:

  • evite escanear el repository y los paquetes de servicio en el contexto de mvc: este contexto solo debería preocuparse por los beans relacionados con mvc. Cuando Spring inyecta un servicio en un controlador, no encontraría el servicio en el contexto de mvc y, por lo tanto, lo buscaría y lo encontraría en el contexto principal. El servicio transaccional sería así inyectado.
  • use un solo contexto: el del servlet, donde se definirían todos los beans en la aplicación.

Debe introducir su administrador de entidades a su administrador de transacciones, de modo que cuando @Transactional anotaciones en su función con @Transactional , cargue instancias del grupo

     

HTH!

Para @Transactional la historia, intente agregar @Transactional al comienzo de su método. Ese fue un problema en mi caso.