S2JSFでダーティリード対応

もう何度目だろう、S2JSFいじり。サンプル追ったり、前に作った軽いシステムの一部を実装してみたりとかしましたが、今回はサンプルの従業員管理画面を、サンプルをカンニングしつつ一から(S2JSFBlankからだけど)実装。

写経とはよくぞ云ったりですよ、本当。こう云うセンスって一番重要ですねぇ。

で、一昨日昨日であらかた動いたんですけど、versionNoでUpdateFailureRuntimeExceptionが出たときの対応がサンプルには無いんですねーこれが。ダーティリード対策は必須なので、やってみますか。

何処で例外を投げるか

サンプルだと、例えば検索条件が宜しく無くてヒット件数0の時、BadCriteriaRuntimeExceptionって自前の例外を投げてますが、これはActionクラスで行っています。

で、キャッチするのはActionThrowsInterceptorってアスペクトで各Actionクラスを横断してやっとる訳です。例外を受けて、そこからメッセージIDやらなにやら取って、JSFのFacesContext#addMessageにつめてます。

が、投げるのがActionでってのがどうにも落ち着かない。

完全webアプリならいいんですけど、同じ業務ロジックをRMIなりWebサービスなりで叩こうかって野望がある場合、処理が分散してしまいそうです。Actionクラスはあくまでも、Webプレゼンテーション層ですよね。JSFの画面IDが戻り値ですから。

特にダーティリード対策の場合、プレゼンテーション層で投げるのはどうにもこうにもアレです。それにActionクラスで投げたらActionThrowsInterceptorにつかまってしまい、無条件でJSF用のエラーメッセージを吐かれてしまいます。

JSF用メッセージは、JSFでしか使えません。多分。うーむ。

YAGNIですか。いいんです!ここは目をつむってGOだ。

んな訳で、取り敢えずBadCriteriaRuntimeExceptionを投げる所をActionクラスからLogicクラスへ移動してみました。

以下、削除コードは線を引いて、追加コードは太字です。ファウラー方式。

●EmployeeSearchActionImpl

    public String checkSearchCount() {
        if(employeeLogic.getSearchCount(employeeSearchDto) == 0){
            throw new BadCriteriaRuntimeException();
        }
        employeeLogic.getSearchCount(employeeSearchDto);
        
        return "employeeList";
    }
●EmployeeLogicImpl

    public int getSearchCount(EmployeeSearchDto dto) {
        return employeeDtoDao.getSearchCount(dto);
        int searchCount = employeeDtoDao.getSearchCount(dto);
        if(searchCount == 0){
            throw new BadCriteriaRuntimeException();
        }
        return searchCount;         
    }

結果は、ばっちり、例外はそのままActionクラスまで渡って、ActionThrowsInterceptorでキャッチされてJSFのエラーメッセージに表示されました。

これで方針は決まった。例外はLogicクラスで投げるどー。つづく。