【问题标题】:Spring Data JPA CDI integration fails with Wildfly SwarmWildfly Swarm 的 Spring Data JPA CDI 集成失败
【发布时间】:2017-02-21 19:28:55
【问题描述】:

我在让 Spring Data JPA 在 Wildfly Swarm 中工作时遇到问题。我第一次尝试执行插入时,出现事务异常。随后的每个插入都很好。我尝试将我的服务范围更改为 @RequestScope 和 @Stateless 而不是 @ApplicationScope,我已经尝试了此处显示的实体管理器设置:

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpd.misc.cdi-integration

我也尝试过使用和不使用持久性单元配置中的最后两行。没有这些,它仍然以同样的方式失败。

还尝试了 spring @Transactional 注释,但这根本不会创建事务(自然在这种情况下)。

这是异常跟踪:

Caused by: javax.persistence.TransactionRequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
    at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:877)
    at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:579)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:506)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    at com.sun.proxy.$Proxy87.save(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100)
    at org.jboss.weld.proxies.CrudRepository$EmployeeScheduleRepo$1416420309$Proxy$_$$_WeldClientProxy.save(Unknown Source)
    at com.books.employeescheduler.services.EmployeeScheduleService.save(EmployeeScheduleService.java:36)
    at com.books.employeescheduler.services.EmployeeScheduleService$Proxy$_$$_WeldSubclass.save$$super(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.proxy.TerminalAroundInvokeInvocationContext.proceedInternal(TerminalAroundInvokeInvocationContext.java:49)
    at org.jboss.weld.interceptor.proxy.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:77)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:117)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:53)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:76)
    at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:74)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeAroundInvoke(InterceptorMethodHandler.java:84)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:72)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:56)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:79)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:68)
    at com.books.employeescheduler.services.EmployeeScheduleService$Proxy$_$$_WeldSubclass.save(Unknown Source)
    at com.books.employeescheduler.services.EmployeeScheduleService$Proxy$_$$_WeldClientProxy.save(Unknown Source)
    at com.books.employeescheduler.endpoints.EmployeeScheduleEndpointImpl.save(EmployeeScheduleEndpointImpl.java:33)
    at com.books.employeescheduler.endpoints.EmployeeScheduleEndpointImpl$Proxy$_$$_WeldSubclass.save$$super(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.proxy.TerminalAroundInvokeInvocationContext.proceedInternal(TerminalAroundInvokeInvocationContext.java:49)
    at org.jboss.weld.interceptor.proxy.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:77)
    at com.books.microservice.core.security.ApiKeySecuredImpl.invoke(ApiKeySecuredImpl.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:74)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeAroundInvoke(InterceptorMethodHandler.java:84)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:72)
    at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:56)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:79)
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:68)
    at com.books.employeescheduler.endpoints.EmployeeScheduleEndpointImpl$Proxy$_$$_WeldSubclass.save(Unknown Source)
    at com.books.employeescheduler.endpoints.EmployeeScheduleEndpointImpl$Proxy$_$$_WeldClientProxy.save(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:395)
    ... 34 more

这是我的 CDI 实体管理器:

public class EntityManagerProducer {

    @PersistenceContext
    @Produces
    @Dependent
    public EntityManager entityManager;
}

以及使用事务并从spring数据仓库调用save方法的类:

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;

@ApplicationScoped
@Transactional
public class EmployeeScheduleService {

    @Inject
    private EmployeeScheduleRepo employeeScheduleRepo;

    public EmployeeSchedule save(EmployeeSchedule employeeSchedule) {
        return employeeScheduleRepo.save(employeeSchedule);
    }
}

还有我的持久化单元配置:

     <persistence-unit name="EmployeeSchedulerUnit">
        <jta-data-source>java:jboss/datasources/EmployeeSchedulerDatasource</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="jboss.entity.manager.jndi.name" value="java:/spring/em"/>
            <property name="jboss.entity.manager.factory.jndi.name" value="java:/spring/emf"/>
        </properties>
    </persistence-unit>

【问题讨论】:

  • 如果您自己实例化SimpleJpaRepository(Class&lt;T&gt; domainClass, EntityManager em) 并调用save(…),也会发生同样的情况吗?
  • @mp911de 你知道,它看起来确实是这样工作的。那么CDI如何实例化repo实例有问题吗?不过,我仍然不确定如何修复它,因为我不确定如何为实际工作的 repo 接口创建生产者。
  • 您愿意在jira.spring.io/browse/datajpa 中提出问题吗?否则我明天再做。
  • @mp911de 创建了问题。感谢您的建议! jira.spring.io/browse/DATAJPA-981
  • 我在 J2EE + Wildfly 10 环境中遇到了完全相同的问题。你解决了这个问题吗?您能否发布您自己问题的答案?谢谢。

标签: java spring-data spring-data-jpa wildfly wildfly-swarm


【解决方案1】:

我在另一个帖子中找到了答案:Spring Data JPA repositories use in EJB timer causes TransactionRequiredException

正如接受的答案中所述,解决方案是将@Eager 注释放在Jpa Repository 接口中。

【讨论】:

  • 不幸的是,我最终没有把它修好,并且已经离开了那家公司,但很高兴知道我应该做什么!
猜你喜欢
  • 2012-05-21
  • 2018-05-11
  • 2015-01-14
  • 2021-10-29
  • 2017-09-22
  • 2014-07-02
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多