私は(少なくとも)Web層(UIのみ)とサービス層を持つエンタープライズアプリケーションを持っています。サービス層ではすべてのビジネスロジックと現在の会話状態が@Stateful @LocalBean
EJB(CDIなし)として実装されています。Web層の会話スコープで使用されるビジネス層内のステートフルEJB
これは、CDIの点で、@SessionScoped
beanと多少似ています。
ここに問題があります。 ウェブ層(@Named @ConversationScoped
)で長時間実行されている会話があり、ステートフルEJBにアクセスしたいとします。この会話の異なるコントローラ(Bean)でEJBにアクセスする必要があります。私はこのようにすることはできません:@EJB
特定のEJBタイプの別のインスタンスになるためです。私は何とかEJBへの参照を保存する必要があります。これは私の現在のソリューションです:
@EJB
private MyEJB _myEJB; // a stateful EJB
@Produces
@Builder // custom quallifier
@ConversationScoped
public MyEJB produceMyEJB() {
return _myEJB;
}
今、私はこの@Inject @Builder MyEJB _myEJB
ような対話スコープのコントローラのそれぞれに、ステートフルEJBの同じインスタンスにアクセスすることができます。
ほとんどの場合、動作します。しかし、いくつかの長時間実行されているテストでは、このリファレンスはnullであり、なぜかわからない。
私はGlassfishのののserver.logに、このスタックトレースを取得:
javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key:
907f0200001f-ffffffffc3388fbb-761
および/または
Cannot load from BACKUPSTORE FOR Key: <907f0200001f-ffffffffc3388fbb-761>
これがなぜ起こるかあなたが任意のアイデアを持っていますか?私の悪い英語を助けてくれてありがとう。
こんにちは、あなたのanwserに感謝します。しかし、EJBにはこのようなStatefulTimeoutアノテーションはありません。このタイムアウトのデフォルト設定(未使用EJBの削除)は90分です(localhost:4848を使用してEJBコンテナ設定を参照)。これはweb.xmlのセッションタイムアウト(および会話)よりもはるかに多いものです。私は何かが欠けていましたか? – kalamar
私の例(Java EE標準)に示すように、@StatefulTimeoutアノテーションを使用して、特定のEJBのタイムアウトを設定できます。すべてのステートフルセッションBeanのデフォルトを変更する場合は、サーバー固有です。 Glassfishを使用していませんが、glassfish-ejb-jar.xmlのremove-timeout-in-seconds属性が、探しているものかもしれません。http://docs.oracle.com/cd/E18930_01/html/ 821-2417/beaqm.html –