2013-02-06 17 views
7

私たちはアプリケーションでJSF、Spring、およびJPAを使用しています。私たちは、プロジェクトの例外処理戦略を単純化しようとしています。Spring/JPA/JSFでの例外処理ストラテジ

当社のアプリケーションのアーキテクチャは、以下のようなものです:

UI(JSF) - >管理Bean - >サービス - > DAO

私たちは、DAO層のための例外翻訳ビーンポストプロセッサを使用しています。これは、Springアプリケーションコンテキストファイルで設定されます。

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 

ここで、Springはすべてのデータベース例外を「org.springframework.dao.DataAccessException」にラップします。私たちはDAOレイヤーで他の例外処理を行っていません。

当社の戦略は、以下のような例外を処理するには:

プレゼンテーション層:

Class PresentationManangedBean{ 

try{ 
     serviceMethod(); 
    }catch(BusinessException be){ 
     // Mapping exception messages to show on UI 
    } 
    catch(Exception e){ 
     // Mapping exception messages to show on UI 
    } 

} 

サービス層

@Component("service") 
Class Service{ 

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = BusinessException.class) 
public serviceMethod(){ 

    try{ 

     daoMethod(); 

    }catch(DataAccessException cdae){ 
     throws new BusinessException(); // Our Business/Custom exception 
    } 
    catch(Exception e){ 
     throws new BusinessException(); // Our Business/Custom exception 
    } 
} 

} 

DAO層

@Repository("dao") 
Class DAO{ 

public daoMethod(){ 
    // No exception is handled 
    // If any DataAccessException or RuntimeException is occurred this 
    // is thrown to ServiceLayer 
} 

} 

質問: 私達はちょうど上記のアプローチは、ベストプラクティスのとおりであるかどうかを確認したいです。そうでない場合は、例外処理(トランザクション管理を行う)に最も適した方法を提案してください。

+0

私はまた、このapprochをフォローしたいが、私は例外をキャッチし、私たちのカスタム例外をスローしたときに、私の例外ハンドラは、そのexcetionをCATHありません。 Springは私の例外を 'org.springframework.transaction.TransactionSystemException'にラップします。これは私の質問http://stackoverflow.com/questions/28295684/unable-to-wrap-dao-exception-in-service-layer-using-spring-mvcです。どうすれば問題を解決できますか? –

答えて

1

このアプローチは私にとってはうまく見えます。私たちはこのプロジェクトで同じアプローチを使用しています。

ビナイ

0

あなたのアプローチは、Springフレームワークの勧告に沿った非常に多くあり、また、アプリケーションのレイヤーでチェック例外の浸透多くを回避できます。 DAOで春のDAEをキャッチしない

-I:

1

私は別のアプローチを使用します。コントローラ(JSFマネージドBean)にそれらを流すようにしました。

コントローラでは、例外(「キャッチ」は1つのみ)をキャッチします。

-Iパラメータにキャッチされた例外を受け取るカスタム "handleException"メソッドを呼び出します。

- この例外ハンドラは、(たとえばif-then-else文で)どのような例外がパラメータであるかをチェックし、その種の例外に従ってメッセージをユーザに表示します。私のケースでは、メッセージのキー(およびもしあればargs)が例外の属性であるプロパティファイルにメッセージを表示します(私はそれを投げるときにそこに置く)。特に、DAEを特別な方法で処理したい場合は、この例外ハンドラメソッドに "if"ブランチを置き、必要な処理を行います。

例外的な処理が1つのポイントであり、すべてのレベルであまりにも多くの "throws-try-catch"をコントローラに置く必要がないので、 JSF)。

もちろん、あなたが「のtry-catchを」特定の例外のサービスでは、あなたがその特定のケースでやりたいことの代わりに、ユーザーにメッセージを表示するので、いくつかのビジネスロジックであれば使用することができます。

あなたがコントローラで春DAEに対処したくない場合も、あなた自身と再スローのビジネス例外にそれをラップすることができます。しかし、これはDAOではなく、サービス層で行います。

この回答が役立ちます。

0

BusinessExceptionをスローするときに例外が発生したときに、同じBusinessExceptionをスローするときに発生する可能性があります。それらを分離しようとする。ところで、なぜあなたはBusinessExceptionをキャッチするときに同じ例外をスローしますか?

+0

コメントありがとうございました...私は見て、あなたに戻ってきます –

0

私は自分自身がこれに混乱していたので、私はいくつかの研究をしていました。しかし、私は少し異なるテイクを持っています。

理論的には、複数のレイヤーでの例外のスローやキャッチは、パフォーマンスとコードの可読性の面でコストがかかります。 Cruxは、そのサービスメソッドは例外をスローするべきではありません。代わりに、ステータス、メッセージ、および出力エンティティをカプセル化する必要があるレスポンスを返す必要があります。コントローラは、複数のサービスメソッドを呼び出し、応答の組み合わせに基づいてペイントしようとした場合

しかし、それは、try catchブロックでそれを入れて、例外を処理することができます。

このロジックを使用すると、sprint mvcとrest mvcを同じように処理できます。あなたの考えを聞かせてください。

Class PresentationManangedBean{ 
     try { 
     Response resp1 = serviceMethod(); 
     if (resp1.getStatus().equals("SUCCESSFUL")) 
      // handle UI painting logic. 
     else 
      // handle error for UI 
     Response resp2 = serviceMethod2(); 
     if (resp.getStatus().equals("SUCCESSFUL")) 
      // handle UI painting logic. 
     else 
      // handle error for UI 
     // handle resp1 and resp2 to paint UI. 
    } catch (Exception e) { 
      // handle error for UI 
    } 
} 

1)サービスはすべての例外を処理する必要があります。コントローラは例外を処理すべきではありません。 2)