4

環境

を使用して定期的なバックグラウンド タスクをスケジュールしたいと考えていManagedScheduledExecutorServiceます。を介してRunnables/ sを取得するので、タスク内でインジェクション機能を使用できます。CallableInstance

私のアプリケーションは で実行されTomEE 7.0.0-SNAPSHOT webprofileます。

問題

これらのタスクはデータベースにアクセスしているため、トランザクションが必要です。ただし、Runnable/Callableの内部ではトランザクションはアクティブではありません。

ユーザー取引

ManagedScheduledExecutorServiceのドキュメントには、

トランザクションが必要な場合は、javax.transaction.UserTransaction インスタンスを使用してください。Resource アノテーションを使用して UserTransaction オブジェクトの注入を要求することにより、UserTransaction インスタンスを使用できます (...)。

ただし、注入された

@Resource
private UserTransaction userTransaction;

nullタスクを呼び出すときです。

ステートレス Bean

私がとったもう 1 つのアプローチは、ステートレス EJB をタスクに挿入することでした。これにより、トランザクションが作成されることを期待していました。

これにより、起動時に次の例外が発生しました。

SEVERE: CDI Beans module deployment failed
java.lang.IllegalStateException: no interface to proxy for ejb StatelessEjb, is this is a MDB maybe you shouldn't use a scope?
    at org.apache.openejb.cdi.CdiEjbBean.createEjb(CdiEjbBean.java:252)
    at org.apache.openejb.cdi.CdiPlugin.getSessionBeanProxy(CdiPlugin.java:224)
    at org.apache.webbeans.container.BeanManagerImpl.getEjbOrJmsProxyReference(BeanManagerImpl.java:951)
    at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:777)
    at org.apache.webbeans.container.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:651)
    at org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:111)
    at org.apache.webbeans.inject.InjectableConstructor.createParameters(InjectableConstructor.java:109)
    at org.apache.webbeans.inject.InjectableConstructor.doInjection(InjectableConstructor.java:72)
    at org.apache.webbeans.portable.InjectionTargetImpl.newInstance(InjectionTargetImpl.java:190)
    at org.apache.webbeans.portable.InjectionTargetImpl.produce(InjectionTargetImpl.java:173)
    at org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:172)
    at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:127)
    at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:67)
    at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:68)
    at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:124)
    at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:785)
    at org.apache.webbeans.inject.instance.InstanceImpl.create(InstanceImpl.java:306)
    at org.apache.webbeans.inject.instance.InstanceImpl.get(InstanceImpl.java:123)
(...)

テストケース

Githubで小さなテスト ケース プロジェクトを作成しました。これには、上記の問題を示す 2 つのブランチが含まれています。

質問

  • @Statelessすべてのインスタンスがインジェクションを使用して取得されるため、EJB は正常に動作するはずではありませんか?
  • なぜ@Resource注射はUserTransaction失敗するのですか?
4

1 に答える 1

5

CDI を使用して取得し、修正する必要があります。

@Inject
private UserTransaction userTransaction;

編集: @Resource ケースの問題は修正されました: https://issues.apache.org/jira/browse/TOMEE-1672

于 2015-12-01T16:36:51.213 に答える