Ошибка интеграции Spring Data JPA CDI с Wildfly Swarm

У меня проблема с работой Spring Data JPA в Wildfly Swarm. При первой попытке выполнить вставку возникает исключение транзакции. Каждая последующая прошивка проходит нормально. Я попытался изменить объем своих сервисов на @RequestScope и @Stateless вместо @ApplicationScope, я пробовал обе настройки entitymanager, показанные здесь:

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

А вот мой entitymanager для CDI:

public class EntityManagerProducer {

    @PersistenceContext
    @Produces
    @Dependent
    public EntityManager entityManager;
}

И класс, который использует транзакцию и вызывает метод сохранения из репозитория весенних данных:

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>

person CorayThan    schedule 12.10.2016    source источник
comment
Произойдет ли то же самое, если вы сами создадите экземпляр SimpleJpaRepository(Class<T> domainClass, EntityManager em) и вызовете save(…)?   -  person mp911de    schedule 13.10.2016
comment
@ mp911de Знаете, похоже, так оно и есть. Так что-то не так с тем, как CDI создает экземпляр репо? Я все еще не уверен, как это исправить, потому что я не уверен, как сделать продюсера для интерфейса репо, который действительно работает.   -  person CorayThan    schedule 13.10.2016
comment
Не могли бы вы зарегистрировать проблему в jira.spring.io/browse/datajpa? В противном случае я сделаю это завтра.   -  person mp911de    schedule 13.10.2016
comment
@ mp911de Создал проблему. Спасибо за предложение! jira.spring.io/browse/DATAJPA-981   -  person CorayThan    schedule 13.10.2016
comment
У меня такая же проблема со средой J2EE + Wildfly 10. Вы решили эту проблему? Не могли бы вы опубликовать ответ на свой вопрос? Спасибо.   -  person Ena    schedule 08.02.2017


Ответы (1)


Я нашел ответ в другом сообщении: Репозитории Spring Data JPA использование в таймере EJB вызывает исключение TransactionRequiredException

Как указано в принятом ответе, решение состоит в том, чтобы поместить аннотацию @Eager в интерфейс репозитория Jpa.

person Ena    schedule 08.02.2017
comment
К сожалению, я не смог исправить это и с тех пор покинул эту компанию, но приятно знать, что я должен был сделать! - person CorayThan; 13.02.2017