存储库在EJB定时器中使用导致TransactionRequir

存储库在EJB定时器中使用导致TransactionRequir

本文介绍了Spring Data JPA存储库在EJB定时器中使用导致TransactionRequiredException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我想在我的Java EE项目中使用spring数据存储库。我使用: WildFly 10.0.0 Hibernate 5.0.7 Spring数据JPA 1.10.6 CDI而不是Spring DI 我创建了以下类和接口: @Entity public class TestEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)私人长ID; @NotNull @Size(min = 1,max = 32) @Column(name =name) private String name; public Long getId(){ return id; } public void setId(Long id){ this.id = id; } public String getName(){ return name; } public void setName(String name){ this.name = name; 我的存储库 @Repository public interface TestRepository扩展CrudRepository< TestEntity,Long> {列表< TestEntity> findByName(String name); 我的CDI配置 public class CdiConfig { @Produces @Dependent @PersistenceContext public EntityManager entityManager; 我的EJB Bean @Stateless public class TestEJB { @Inject TestRepository testRepository; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void testRepository(){ TestEntity testEntity = new TestEntity(); testEntity.setName(Some name); this.testRepository.save(testEntity); 我的persistence.xml: < persistence 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_2_0.xsd version =2.0> < persistence-unit name =[my data source]transaction-type =JTA> < jta-data-source> java:/ [我的数据源]< / jta-data-source> <映射文件> META-INF / database-views.xml< / mapping-file> <属性> < property name =hibernate.dialectvalue =org.hibernate.dialect.PostgreSQL9Dialect/> < property name =hibernate.hbm2ddl.autovalue =create/> < property name =hibernate.show_sqlvalue =false/> < property name =hibernate.format_sqlvalue =false/> < property name =hibernate.connection.isolationvalue =2/> < property name =hibernate.transaction.factory_classvalue =org.hibernate.transaction.JTATransactionFactory/> < property name =hibernate.transaction.manager_lookup_classvalue =org.hibernate.transaction.JBossTransactionManagerLookup/> < property name =hibernate.jndi.urlvalue =java:/ TransactionManager/> < / properties> < / persistence-unit> < /余辉> 如果我第一次调用testRepository方法(我使用调度器),那么我会得到下面的异常: 20:34:22,934错误[org.jboss.as.ejb3](EJB默认值 - 1)WFLYEJB0020:错误调用定时器超时:[id = 4aae5730-1652-4908-9a8a-7283e5adb2f0 timedObjectId = module-ear-1.0-SNAPSHOT.module-test-1.0-SNAPSHOT.TestScheduler auto-timer?:true persistent?:false timerService = org.jboss .as.ejb3.timerservice.TimerServiceImpl @ 39ec0a90 initialExpiration = null intervalDuration(以毫秒为单位)= 0 nextExpiration = Thu Jan 12 20:34:25 CET 2017 timerState = IN_TIMEOUT info = null]:javax.ejb.EJBTransactionRolledbackException:WFLYJPA0060:Transaction需要在org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:159)处执行此操作(使用事务或扩展持久化上下文)。 as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:256) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:329) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)。在组织.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) at org.jboss .invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100) at org.jboss.invocation.InterceptorContext .proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptor Factory $ 1.processInvocation(ShutDownInterceptorFactory.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor .processInvocation(LoggingInterceptor.java:66)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor .java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java :54) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340 ) at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636) at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)处org.jboss.invocation.InterceptorContext org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)。运行(InterceptorContext.java:356) at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ViewService $ View.invoke(ViewService.java:195) at org.jboss.as.ee.component.ViewDescription $ 1.processInvocation(ViewDescription.java:185) org.jboss .invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ProxyInvocationHandler .invoke(ProxyInvocationHandler.java:73) at com.module.test.TestEJB $$$ view5.testRepository(Unknown Source) at com.module.test.TestScheduler.test(TestScheduler.java: 23) 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.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java: 52)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.invocation.WeavedInterce ptor.processInvocation(WeavedInterceptor.java:57) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory $ 1.processInvocation(UserInterceptorFactory.java:61) at org.jboss.invocation.InterceptorContext .proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext $ Invocation.proceed(InterceptorContext.java:437) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception (Jsr299BindingsInterceptor.java:82) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:95) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory $ 1.processInvocation(UserInterceptorFactory.java:61)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java: 57) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory $ 1.processInvocation(U serInterceptorFactory.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor。 java:43) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext $ Invocation.proceed(InterceptorContext.java:437) at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73) at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) at org.jboss .invocation.InterceptorContext.proceed(国际米兰 at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:52)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.as.ejb3.component.singleton.SingletonComponentInstanceAssociationInterceptor.processInvocation(SingletonComponentInstanceAssociationInterceptor.java:53)。在组织.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275) at org.jboss.as .ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:327)org.jboss .as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3 .component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.security .SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext $ Invocation.proceed(InterceptorContext .java:437) at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:110) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340 )在org.jboss.as.ejb3.component.intercept处 ors.ShutDownInterceptorFactory $ 1.processInvocation(ShutDownInterceptorFactory.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.component.NamespaceContextInterceptor .processInvocation(NamespaceContextInterceptor.java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation (AdditionalSetupInterceptor.java:54) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)在org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)在org.wildfly。 security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager。 at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80) at org.jboss.invocation.InterceptorContext .proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ejb3.timerservice.TimedObjectInvokerImpl.callTimeout(TimedObjectInvokerImpl .java:104) at org.jboss.as.ejb3.timerservice.CalendarTimerTask.invokeBeanMethod(CalendarTimerTask.java:64) at org.jboss.as.ejb3.timerservice.CalendarTimerTask.callTimeout(CalendarTimerTask .java:53) at org.jboss.as.ejb3.timerservice.TimerTask.run(TimerTask.java:1 55) at org.jboss.as.ejb3.timerservice.TimerServiceImpl $ Task $ 1.run(TimerServiceImpl.java:1221) at org.wildfly.extension.requestcontroller.RequestController $ QueuedTask $ 1.run( $ java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)$ java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) 在java.lang.Thread.run(Thread.java:745)在org.jboss.threads.JBossThread.run(JBossThread.java:320)引起:javax.persistence .TransactionRequiredException:WFLYJPA0060:在org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:877)$ b $上执行此操作(使用事务或扩展持久化上下文)需要事务 b at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:579) at org.springframework.data.jpa.repository.support.SimpleJpaRepositor y.save(SimpleJpaRepository.java:506)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)。在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.data.repository.core。 $ or $。 at org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488) 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)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)。在org.springframework.data .projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)在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)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)在org.springframework.aop.framework.JdkDynamicAopProxy.invoke (JdkDynamicAopProxy.java:208) at com.sun.proxy $ Proxy132.save(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)。在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)在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 $ TestRepository $ 614971258 $ Proxy $ _ $$ _ WeldClientProxy.save(Unknown Source) at com.module.test.TestEJB.testRepository (TestEJB.java:35)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect .DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.as.ee.component.ManagedReference MethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext $ Invocation.proceed(InterceptorContext。 Java的:437)处org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82)。 在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java) :340) at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340 )在org.jboss.as.jpa.interceptor.SBInvocationInterceptor处 .processInvocation(SBInvocationInterceptor.java:47) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext $ Invocation.proceed(InterceptorContext.java :437) at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64) at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83 ) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45)在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)位于org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21)位于org.jboss.invocation。 InterceptorContext.proceed(InterceptorContext.ja va:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java: at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(PooledInstanceInterceptor.java:51) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:254) ... 103 more 如果我第二次调用testRepository方法,那么一切正常。此外,如果从存储库中删除findByName方法,则不会发生此问题(该方法从不调用)。为什么? 我的项目可以在这里找到: https://github.com/spacerowicz/spring-repository-test 解决方案 简短回答 存储库初始化会中断事务。通过将 @Eager 添加到您的存储库实例中,在不同的线程/事务中预先初始化存储库。 解释 Spring数据存储库实例是 @ApplicationScoped ,并根据需要初始化。执行首次访问资源库的线程(和事务)用于初始化。 Spring数据库初始化做了几件事,其中一个是试图弄清楚,是否提供了命名查询用于存储库查询方法。不幸的是,JPA没有提供API来检查是否存在命名查询,所以我们依靠 EntityManager.createNamedQuery(...)。如果没有命名查询, EntityManager 会抛出异常并中止事务。 在稍后的阶段,您的EJB方法在同一个线程(和事务)内使用 EntityManager 。它检查一个活动的事务。由于事务标记为只回滚,因此您会看到异常。 解决方法 添加 @Eager 到你的仓库声明。 Spring Data CDI扩展将在启动时初始化存储库: @Eager public interface TestRepository扩展CrudRepository< TestEntity,龙> { // ... } 提示 在 TestRepository 上不需要 @Repository 。 Spring Data通过从 org.springframework.data.repository.Repository 获取后代bean或使用 @RepositoryDe​​finition 。 您的 persistence.xml 中的事务管理器属性不是必需的,WildFly已经 参考文献: DATAJPA-724 DATAJPA-617 I would like to use spring data repositories in my Java EE project. I use:WildFly 10.0.0Hibernate 5.0.7Spring Data JPA 1.10.6CDI instead of Spring DII have created the following classes and interfaces:@Entitypublic class TestEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NotNull @Size(min = 1, max = 32) @Column(name = "name") private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}My repository@Repositorypublic interface TestRepository extends CrudRepository<TestEntity, Long> { List<TestEntity> findByName(String name);}My CDI Configurationpublic class CdiConfig { @Produces @Dependent @PersistenceContext public EntityManager entityManager;}My EJB Bean@Statelesspublic class TestEJB { @Inject private TestRepository testRepository; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void testRepository() { TestEntity testEntity = new TestEntity(); testEntity.setName("Some name"); this.testRepository.save(testEntity); }}My persistence.xml:<persistence 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_2_0.xsd" version="2.0"> <persistence-unit name="[my data source]" transaction-type="JTA"> <jta-data-source>java:/[my data source]</jta-data-source> <mapping-file>META-INF/database-views.xml</mapping-file> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/> <property name="hibernate.hbm2ddl.auto" value="create"/> <property name="hibernate.show_sql" value="false"/> <property name="hibernate.format_sql" value="false"/> <property name="hibernate.connection.isolation" value="2"/> <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/> <property name="hibernate.jndi.url" value="java:/TransactionManager"/> </properties> </persistence-unit></persistence>If I invoke testRepository method (I use scheduler for this purpose) first time then I get the following exception:20:34:22,934 ERROR [org.jboss.as.ejb3] (EJB default - 1) WFLYEJB0020: Error invoking timeout for timer: [id=4aae5730-1652-4908-9a8a-7283e5adb2f0 timedObjectId=module-ear-1.0-SNAPSHOT.module-test-1.0-SNAPSHOT.TestScheduler auto-timer?:true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@39ec0a90 initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Thu Jan 12 20:34:25 CET 2017 timerState=IN_TIMEOUT info=null]: javax.ejb.EJBTransactionRolledbackException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context) at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:159) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:256) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:329) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:66) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:54) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636) at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:195) at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:185) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:73) at com.module.test.TestEJB$$$view5.testRepository(Unknown Source) at com.module.test.TestScheduler.test(TestScheduler.java:23) 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.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:57) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:95) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:57) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73) at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.singleton.SingletonComponentInstanceAssociationInterceptor.processInvocation(SingletonComponentInstanceAssociationInterceptor.java:53) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:327) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:110) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:54) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636) at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356) at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ejb3.timerservice.TimedObjectInvokerImpl.callTimeout(TimedObjectInvokerImpl.java:104) at org.jboss.as.ejb3.timerservice.CalendarTimerTask.invokeBeanMethod(CalendarTimerTask.java:64) at org.jboss.as.ejb3.timerservice.CalendarTimerTask.callTimeout(CalendarTimerTask.java:53) at org.jboss.as.ejb3.timerservice.TimerTask.run(TimerTask.java:155) at org.jboss.as.ejb3.timerservice.TimerServiceImpl$Task$1.run(TimerServiceImpl.java:1221) at org.wildfly.extension.requestcontroller.RequestController$QueuedTask$1.run(RequestController.java:497) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) at org.jboss.threads.JBossThread.run(JBossThread.java:320)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.$Proxy132.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$TestRepository$614971258$Proxy$_$$_WeldClientProxy.save(Unknown Source) at com.module.test.TestEJB.testRepository(TestEJB.java:35) 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.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82) at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:93) at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64) at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(PooledInstanceInterceptor.java:51) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:254) ... 103 moreIf I invoke testRepository method second time then everything is ok. Moreover, the problem does not occur if I remove findByName method from repository (this method is never invoked). Why?My project is available here: https://github.com/spacerowicz/spring-repository-test 解决方案 Short answerThe repository initialization breaks the transaction. Initialize the repository beforehand, in a different Thread/transaction by adding @Eager to your repository instances.ExplanationSpring Data repository instances are @ApplicationScoped and initialized on demand. The Thread (and transaction) that performs the first access to the repository is used for initialization.Spring Data JPA repository initialization does a couple of things, one of them is trying to figure out, whether you have provided named queries for repository query methods. Unfortunately, JPA does not provide an API to check whether a named query exists, so we rely on EntityManager.createNamedQuery(…). If there's no named query, EntityManager throws an exception and aborts the transaction.In a later stage, your EJB method uses the EntityManager within the same Thread (and transaction). It checks for an active transaction. Because the transaction is marked for rollback-only, you see the exception.WorkaroundAdd @Eager to your repository declaration. The Spring Data CDI extension will initialize the repository on startup:@Eagerpublic interface TestRepository extends CrudRepository<TestEntity, Long> { // …}HintYou don't require @Repository on TestRepository. Spring Data picks up the repository by picking up beans that are descendants from org.springframework.data.repository.Repository or plain interfaces annotated with @RepositoryDefinition.The transaction manager properties in your persistence.xml are not required, WildFly already configures the persistence context with the required settings.References:DATAJPA-724DATAJPA-617Strange exception on inital request to Repository when using Spring Data JPA with EJB/CDI 这篇关于Spring Data JPA存储库在EJB定时器中使用导致TransactionRequiredException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-12 23:21