Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring JPA没有正在进行的事务_Java_Spring_Hibernate_Spring Mvc_Jpa - Fatal编程技术网

Java Spring JPA没有正在进行的事务

Java Spring JPA没有正在进行的事务,java,spring,hibernate,spring-mvc,jpa,Java,Spring,Hibernate,Spring Mvc,Jpa,我刚接触Spring和JPA,浪费了5天时间,在网上搜索没有结果。我想将对象保存到SQL SERVER,连接是正确的,但当我写入.flush()时,会出现异常 嵌套异常为javax.persistence.TransactionRequiredException:否 交易正在进行中 这是我的jpaContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframe

我刚接触Spring和JPA,浪费了5天时间,在网上搜索没有结果。我想将对象保存到SQL SERVER,连接是正确的,但当我写入.flush()时,会出现异常

嵌套异常为javax.persistence.TransactionRequiredException:否 交易正在进行中

这是我的jpaContext.xml

     <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<context:annotation-config />
<context:component-scan base-package="com.misha.service"/>
<context:component-scan base-package="com.misha.repository"/>
<context:component-scan base-package="com.misha.model"/>

<bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="myEntityManager"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.misha.model"/>
    <property name="persistenceUnitName" value="test" /> 
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
        </props>
    </property>
</bean>
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
    <property name="url"
        value="jdbc:jtds:sqlserver://127.0.0.1;instance=SQLEXPRESS;DatabaseName=misha" />
    <property name="username" value="sa" />
    <property name="password" value="root" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEntityManager" />
</bean>

  <tx:annotation-driven transaction-manager="transactionManager"/>  

</beans>
最后是我的存储库实现:

@Service("manService")
public class SaveManImpl implements SaveMan {
//  
    @Autowired
    private ManRepositoryImpl manRepo;


    @Transactional
    public Table1 save(Table1 table) {
        manRepo.save(table);
        return null;
    }

}
@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 annotation,对吗?我试着把注释放在存储库保存方法上面,没有结果,在这个上面的服务保存方法之后,这里也是一样。提前谢谢

我在控制器中调用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配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <mvc:annotation-driven />
    <!--<mvc:resources location="pdfs" mapping="/pdfs/**" />
    <mvc:resources location="/resources" mapping="/resources/**"/> -->
    <context:component-scan base-package="com.misha.controllers"></context:component-scan>
    <context:component-scan base-package="com.misha.repository" />
    <context:component-scan base-package="com.misha.service" />

    <context:annotation-config/>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
        <property name="order" value="0"></property>
    </bean>


<bean id="contentNegotiatingViewResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="order" value="1" />
  <property name="mediaTypes">
    <map>
      <entry key="json" value="application/json" />
      <entry key="xml" value="application/xml" />
      <entry key="request" value="text/html" />
    </map>
  </property>
  <property name="favorPathExtension" value="false" />
  <property name="favorParameter" value="true" />
  <property name="defaultViews">
    <list>

    </list>
  </property>
</bean>

<bean class="org.springframework.context.support.ResourceBundleMessageSource"  >
    <property name="basename" value="WEB-INF/messages"></property>

</bean>


</beans>

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

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven />


您有两个Spring上下文:

  • 主版本由jpaContext.xml配置,其中来自服务和存储库包的bean被扫描,并由事务拦截器代理

  • mvc文件,由另一个xml文件(您没有命名)配置,其角色是描述应用程序的mvc部分,即定义和配置控制器bean、视图解析器等。此上下文是主上下文的子上下文

  • 问题在于,您还可以在此子上下文中扫描服务和存储库包。因此,每个服务和存储库都有两个实例:

    • 一个在主上下文中,这是事务性的
    • 一个在子上下文中,而不是(因为子上下文不关心事务管理)
    因此,控制器被注入来自与控制器相同的上下文的服务:非事务性服务

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

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

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

    要使故事简短,请尝试在方法的开头添加
    @Transactional
    。在我的例子中,这是一个问题。

    您能发布完整的堆栈跟踪吗?并在获取SaveMan实例并调用其save()方法的地方发布代码。顺便问一下:如果您注入并使用具体类,为什么要定义接口?如果你的方法返回null,为什么会返回Table1?看起来你的jpaContext.xml配置被切断了。你能修复发布完整配置,包括bean“transactionManager”@RohitJain的定义吗?我已经用完整配置更新了问题stack@JBNizet我从控制器调用它,我已经编辑了代码,请参见。如果返回null,为什么方法返回Table1?我不在乎它返回什么,我只想将对象保存到DBA,因为我可以看到,如果尚未定义该对象,应用程序将不会启动。它不在发布的配置中,但它必须存在………否?我已将(也编辑了该问题)添加到jpaContext.xml,但没有结果,仍然是:HTTP状态500-请求处理失败;嵌套的异常为javax.persistence.TransactionRequiredException:中没有事务progress@alan是的,它是必需的,好的:)@Misha,你添加了吗?如果以前没有这个配置,我甚至看不出应用程序是如何启动的。我现在添加了这些配置,它可以工作是因为@JB Nizet answer你知道你是谁吗?你是我的英雄!!!非常感谢,我已经从drispatcher servlet扫描中删除了服务和存储库,并且成功了。非常感谢你!那会过去的,别担心:)我在servlet配置文件中完成了所有配置,它对我很有效,非常感谢你的帮助:)@JBNizet你能看看这个问题吗。我认为我们面临着类似的问题,但使用spring boot。spring boot通过
    @SpringBootApplication
    扫描所有bean,我们不配置任何东西。关于如何避免在spring boot应用程序中从两个上下文加载bean,有什么建议吗?
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>
    <tx:annotation-driven />