Хранилища данных 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, вам необходимо указать эту стратегию транзакций.