2

したがって、問題は非常に単純です。

JSF 2.0 と Primefaces および EJB を使用してアプリケーションを処理していますが、問題が発生しました。@SessionScopedすべての Bean を格納する単一の Bean があり@Stateful Session Beansます。

あるケースでは (JPA からのいくつかの例外を処理しなかった場合)、例外があります。

javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "webuser_idwebuser_pk"
  Detail: Key (idwebuser)=(6) already exists.

それは私たちの 1 つの破壊につながります@Stateful Session Bean。そのため、Web サイトを更新した後、JSF がまだ正しく機能しているときに、フォームに入力して送信しようとした後、その Bean からメソッドを呼び出して例外が発生します。

javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key: 22900a4d007e1f-6dcc714a-0

最も問題なのは、アプリケーションを再起動して再デプロイし、同じコンピューター (または Web ブラウザー) で動作させる必要があることです。これは、JSF の@SessionScopedBean が Cookie などによって保持されているためです。

したがって、私が推測する解決策は、それを強制的に破棄する@SessionScopedか、何らかの方法でセッションを更新することですが、実際にはその方法がわかりません。または、より良いアプローチは何でしょうか。

ありがとう!

4

2 に答える 2

6

これを解決するには、EJB におけるアプリケーション例外とシステム例外の違いに注意する必要があります。

これらは、それぞれチェック例外と実行時例外に大まかに対応しています。

アプリケーション例外は、独自のコードによって処理されることになっているため、トランザクションのロールバックや Bean の破壊は発生しません。システム例外は逆の効果をもたらし、ロールバックと EJB Bean の破壊を引き起こします。

後者の効果は、あなたが見ているものです。JPA は未チェックの例外をスローするため、システム例外となり、SFSB が破棄されます。JSF も CDI マネージド Bean もこの「システム例外」に関与するため、例外を伝播するだけで存続します。

おそらく必要なのは、@ApplicationException で注釈を付けた新しい例外を定義し、そのロールバック属性を true に設定することです。SFSB 内で JPA 例外をキャッチし、カスタム例外でラップして再スローします。

于 2012-08-29T08:50:57.160 に答える
-3

さて、私は自分で答えを見つけました。実際に必要だったのは、ActionListenerImplを拡張してJSFビューで例外を処理することでした。

元の記事はこちら: オリジナル

しかし、私が行ったことは、HTTPセッションを無効にして例外処理を拡張することでした。これにより、最終的に、@SessionScopedManaged Beanの寿命が終わり、SSBの再注入につながりました。このような:

private void gotoErrorPage(MethodExpression expression) {
        FacesContext context = FacesContext.getCurrentInstance();
        Application application = context.getApplication();

        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }

        NavigationHandler navHandler = application.getNavigationHandler();
        navHandler.handleNavigation(context, null == expression ? null : expression.getExpressionString(), NAV_ERRORPAGE);
        context.renderResponse();
    }
于 2012-08-29T09:41:15.247 に答える