環境
を使用して定期的なバックグラウンド タスクをスケジュールしたいと考えていManagedScheduledExecutorService
ます。を介してRunnable
s/ sを取得するので、タスク内でインジェクション機能を使用できます。Callable
Instance
私のアプリケーションは で実行され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
失敗するのですか?