Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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
JPA+Spring:UnexpectedRollbackException当需要事务时,需要新的或嵌套的_Spring_Exception_Jpa_Rollback - Fatal编程技术网

JPA+Spring:UnexpectedRollbackException当需要事务时,需要新的或嵌套的

JPA+Spring:UnexpectedRollbackException当需要事务时,需要新的或嵌套的,spring,exception,jpa,rollback,Spring,Exception,Jpa,Rollback,我正在用Spring、JPA和GlassFish3.1做我的第一个项目,我遇到了一些麻烦。我已经找了一个星期的解决办法,但什么也没找到 我有一个名为Role的实体,一个带有访问任何实体的通用方法的generalRepository,一个实现关于角色的特定方法的RoleRepository,以及一个调用RoleRepository的服务类。服务类的方法是事务性的,但是如果传播属性是必需的,需要新的或嵌套的,我会得到RollBackException。如果传播是强制性的,则会抛出一个异常,说明: o

我正在用Spring、JPA和GlassFish3.1做我的第一个项目,我遇到了一些麻烦。我已经找了一个星期的解决办法,但什么也没找到

我有一个名为Role的实体,一个带有访问任何实体的通用方法的generalRepository,一个实现关于角色的特定方法的RoleRepository,以及一个调用RoleRepository的服务类。服务类的方法是事务性的,但是如果传播属性是必需的,需要新的或嵌套的,我会得到RollBackException。如果传播是强制性的,则会抛出一个异常,说明:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:339)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    ...
如果不支持、从不支持或不支持,则select查询可以正常工作,但如果尝试执行创建、更新或删除查询,则会出现相同的回滚异常

我已经调试了select查询,在它们抛出RollBackException之前,查询会很好地得到结果,异常会在函数的末尾抛出。另外,如果我使用EntityManager的find获取实体,而服务方法没有@Transactional Anotion,则可以正常工作,但如果我将其设置为事务性,则它会崩溃,出现相同的异常

我拥有的所有实体都会发生这种情况,但我用它来解释问题

我认为我的Spring配置有问题,但我不知道是什么

这是异常的完整跟踪,在某些行中有对AuthenticationSuccessHandler类的引用,因为我在其中调用服务类:

WARNING: StandardWrapperValve[default]: PWC1406: Servlet.service() for servlet default threw exception
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: Transaction marked for rollback.
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:845)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:314)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.citius.reservas.service.service$$EnhancerByCGLIB$$37b50d4.tryJPAFind(<generated>)
    at com.citius.reservas.AuthenticationSuccessHandlerImpl.onAuthenticationSuccess(AuthenticationSuccessHandlerImpl.java:47)
    ...
Caused by: javax.transaction.RollbackException: Transaction marked for rollback.
    at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:428)
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:855)
    at com.sun.enterprise.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:208)
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:842)
    ... 45 more
GenericRepository,一个通用类,由所有存储库实现:

public class GenericRepositoryImpl<T> implements GenericRepository<T> {

    @PersistenceContext
    private EntityManager em;

    private Class<T> type;

    public GenericRepositoryImpl( ){
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        type = (Class) pt.getActualTypeArguments()[0];
    }

    @Override
    public T find(Object pk) {
        try{
            return em.find(type, pk);
        }catch(java.util.NoSuchElementException ex){
            return null;
        }
    }

    @Override
    public T create(T t) {
        em.persist(t);
        em.flush();
        em.refresh(t);
        return t;
    }

    @Override
    public List<T> query(Query q) {
        List<T> list= q.getResultList();
        if(list==null)
            list=new ArrayList<T>();        
        return list;
    }
}
Spring配置applicationContext.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
          http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
">
    <context:component-scan base-package="com.***.***" />

    <jpa:repositories base-package="com.***.***.repositories" />

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

    <beans>
        <bean id="EntityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="JPAReservas"/>
        </bean>

        <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

        <bean id="transactionManager" 
            class="org.springframework.transaction.jta.JtaTransactionManager" >
            <property name="allowCustomIsolationLevels">
                <value>true</value>
            </property>
        </bean>
    </beans>
</beans>
Persistence.xml我在GlassFish服务器中创建了一个数据源和一个连接池:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

  <persistence-unit name="JPAReservas" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>Reservas_mysql</jta-data-source>

    <!--Named queries-->
    <mapping-file>META-INF/mapping/Role.xml</mapping-file>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>
  </persistence-unit>
</persistence>
最后,我在一个xml文件中命名了queires,如下所示: 从角色r中选择r


我对Spring和JPA非常在行,所以如果你知道一些改进,或者我可以做的更改,请告诉我。

好的,我已经解决了将事务类型更改为RESOURCE\u LOCAL的问题,但是在Begging,Glassfish给了我很多麻烦。我就是这样解决的:

我已将metadata complete=true添加到web.xml的标题中。解释了为什么需要这样做:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0" metadata-complete="true">
我已经更改了persistence.xml,因为使用RESOURCE_LOCAL,应用程序将不会使用Glassfish的连接池,我必须输入有关数据库连接的信息:

<persistence-unit name="JPAReservas" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <mapping-file>META-INF/mapping/User.xml</mapping-file>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/reservas"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="adminpassword"/>
    </properties>
  </persistence-unit>
最后,我更改了applicationContext.xml Spring配置,因为我不能使用与JTA相同的EntityManager类和RESOURCE_LOCAL:

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

就这些。我不知道为什么我不能像以前那样使用JTA,但我已经解决了!!!:。谢谢大家!

您尝试过在persistence.xml中使用user transaction type=RESOURCE\u LOCAL吗?我尝试过,但它给Glassfish带来了很多问题。好的,我看到这些行重复了:。我不知道这是否会导致一些问题……不,我已经删除了一个,然后删除了另一个,但仍然失败。我在Weblogic 10.3.6中遇到了与Spring数据jpa类似的问题。我注意到,我仍然可以使用JTA,因为我可以在没有事务上下文的情况下(例如在用@TransactionAttributeNEVER注释的方法中)对EJB进行第一次调用。对我来说,问题在于SpringDataJPA在向EntityManager注册NamedQuery时导致事务回滚。因此,您可以尝试设置glassfish EJB池来预创建EJB的一组实例,以便在事务外部初始化JPA存储库。
    <named-query name="Role.findByName">
        <query>SELECT r FROM Role r WHERE r.name = :name</query>
    </named-query>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0" metadata-complete="true">
<persistence-unit name="JPAReservas" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <mapping-file>META-INF/mapping/User.xml</mapping-file>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/reservas"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="adminpassword"/>
    </properties>
  </persistence-unit>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="EntityManagerFactory" />
</bean>