Хранилища данных Deltaspike в Wildfly 8.2 с JTA и транзакцией, управляемой контейнером (CMT)

Я использую хранилища данных DeltaSpike для даосов в проекте, который использует источники данных JTA. Я недавно перешел на Wildfly 8.2 и у меня возникли некоторые проблемы с ними:

Как описано в документации к DeltaSpike, я настроил BeanManagedUserTransactionStrategy как свою TransactionStrategy, написав globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy =org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy в /META-INF/apache-deltaspike.properties

С этой конфигурацией рассмотрим Role, @Repository RoleDao, TestStatelessClass который внедряет RoleDao и печатает строку, и API-интерфейс, который внедряет сервис:

Role.java

@Entity
public class Role implements Serializable {

@Id
private Long id;

@Column(unique=true, nullable=false)
private String role;
// ...
}

RoleDao.java

import org.apache.deltaspike.data.api.EntityRepository;
import org.apache.deltaspike.data.api.Repository;
@Repository
@Dependent
public interface RoleDao extends EntityRepository<Role, Long> {

Role findById(long id);
}

TestStatelessClass.java

@LocalBean
@Stateless
public class TestStatelessClass {
    @Inject RoleDao roleDao;

    public TestStatelessClass() {
    }

    public void execute() {
        System.out.println("Stateless: Count roles: " + roleDao.count());
    }
}

TestAPI.java

@Path("test")
//@Stateless
public class TestAPI {

    @Inject TestStatelessClass tsc;

    @GET
    @Produces("application/json")
    @NoCache
    public List<String> test() throws Exception {

        tsc.execute();

        return null;
    }
}

Когда вызывается tsc.execute (), происходит следующее исключение:

18:39:57,425 ERROR [org.jboss.as.ejb3.invocation] (default task-19) JBAS014134: EJB Invocation failed on component TestStatelessClass for method public void example.scheduler.TestStatelessClass.execute(): javax.ejb.EJBException: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
...
Caused by: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
...
Caused by: javax.ejb.EJBException: javax.enterprise.inject.CreationException
...
Caused by: javax.enterprise.inject.CreationException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [rt.jar:1.7.0_55]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) [rt.jar:1.7.0_55]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) [rt.jar:1.7.0_55]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) [rt.jar:1.7.0_55]
    at java.lang.Class.newInstance(Unknown Source) [rt.jar:1.7.0_55]
    at org.jboss.weld.security.NewInstanceAction.run(NewInstanceAction.java:33) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.7.0_55]
    at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:40) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:50) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:54) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:96) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:370) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:381) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:150) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:742) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:840) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:370) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:381) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:150) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:742) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:762) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.ForwardingBeanManager.getReference(ForwardingBeanManager.java:61) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.bean.builtin.BeanManagerProxy.getReference(BeanManagerProxy.java:89) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.apache.deltaspike.partialbean.impl.PartialBeanLifecycle.createHandlerInstance(PartialBeanLifecycle.java:133) [deltaspike-partial-bean-module-impl-1.3.0.jar:1.3.0]
    at org.apache.deltaspike.partialbean.impl.PartialBeanLifecycle.create(PartialBeanLifecycle.java:68) [deltaspike-partial-bean-module-impl-1.3.0.jar:1.3.0]
    at org.apache.deltaspike.core.util.bean.ImmutableBean.create(ImmutableBean.java:72) [deltaspike-core-api-1.3.0.jar:1.3.0]
    at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:742) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:840) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:370) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:381) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.DefaultInjector$1.proceed(DefaultInjector.java:71) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.DefaultInjector.inject(DefaultInjector.java:73) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.StatelessSessionBeanInjector.inject(StatelessSessionBeanInjector.java:58) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.weld.injection.producer.ejb.SessionBeanInjectionTarget.inject(SessionBeanInjectionTarget.java:140) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
    at org.jboss.as.weld.injection.WeldInjectionContext.inject(WeldInjectionContext.java:39) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:51) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ee.component.AroundConstructInterceptorFactory$1.processInvocation(AroundConstructInterceptorFactory.java:28)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.weld.injection.WeldInterceptorInjectionInterceptor.processInvocation(WeldInterceptorInjectionInterceptor.java:56) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.weld.ejb.Jsr299BindingsCreateInterceptor.processInvocation(Jsr299BindingsCreateInterceptor.java:94) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:273) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
    ... 111 more
...
Caused by: javax.naming.NameNotFoundException: UserTransaction [Root exception is java.lang.IllegalStateException: JBAS014237: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction]
...
Caused by: java.lang.IllegalStateException: JBAS014237: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction

Если вместо класса Contained Managed Transaction я использую класс Stateless Bean Managed Transaction (@Stateless @TransactionManagement(TransactionManagementType.BEAN)), все работает нормально, но менять все классы и контролировать себя транзакция внутри бобов будет болезненно. Кто-нибудь знает причину этой ошибки?

Спасибо заранее за любую помощь!

PS: у меня есть некоторые обходные пути https://issues.apache.org/jira/browse/DELTASPIKE-552 и https://issues.apache.org/jira/browse/DELTASPIKE-420 но они не действительны.

РЕДАКТИРОВАТЬ: Некоторые зависимости POM:

<properties>
    <deltaspike.version>1.3.0</deltaspike.version>
</properties>

    <dependency>
        <groupId>org.apache.deltaspike.modules</groupId>
        <artifactId>deltaspike-data-module-api</artifactId>
        <version>${deltaspike.version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.deltaspike.modules</groupId>
        <artifactId>deltaspike-data-module-impl</artifactId>
        <version>${deltaspike.version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>1.2</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.0.Final</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.servlet</groupId>
        <artifactId>jboss-servlet-api_3.0_spec</artifactId>
        <scope>provided</scope>
    </dependency>

1 ответ

Измени свой apache-deltaspike.properties в

globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy

Поскольку вы создаете CMT, вам необходимо указать эту стратегию транзакций.

Другие вопросы по тегам