[Seasar-user:1356] Re: S2Dao でエラー処理

suga suga_k
2004年 12月 14日 (火) 19:41:35 JST


初めまして、suga と申します。
# 同姓に反応(笑)

On Tue, 14 Dec 2004 18:50:08 +0900 (JST)
須賀 祐一 <[E-MAIL ADDRESS DELETED]> wrote:

> [質問1]
> データベース固有のエラーを取得して処理を分岐させようと考えています。
> エラーコードは以下のようにして取得したのですが、この方法でよいのでしょうか?

今回私が試みた方法を説明します。

まず、Dao にもう一つ aspect をかぶせます。

<component class="example.EmployeeDao">
    <aspect pointcut="insert">alreadyExistsThrows</aspect>
    <aspect>dao.interceptor</aspect>
</component>

insert メソッドで発生した例外を以下の Interceptor で処理します。
例えば HSQLDB の場合はこんな感じ。

import org.seasar.framework.aop.interceptors.ThrowsInterceptor;

public class AlreadyExistsThrowsInterceptor extends ThrowsInterceptor {
    public void handleThrowable(Throwable t, MethodInvocation invocation) {
        if (t instanceof SQLRuntimeException) {
            SQLException e2 = (SQLException) t.getCause();
            if ("23000".equals(e2.getSQLState())) {
                if (e2.getErrorCode() == -104) {
                    throw new AlreadyExistsRuntimeException(e2);
                }
            }
        }
        throw t;
    }
}

これで、一意性制約違反の場合、Dao を使う側は
AlreadyExistsRuntimeException を意識すれば良いことになります。

# 実際に使ったコードを編集していますので、このままでは使えないかも。


> [質問2]
> 部署ごとに使用するデータベースサーバの種類が違う為、
> データベースによってエラーの処理を変えたいと考えているのですが、
> データベースの名称を取得する方法は無いのでしょうか?

で、上記のハードコーディングな SQLState も ErrorCode も DBMS 依存なので、
S2Dao が内部でやっているように

Connection con = DataSourceUtil.getConnection(dataSource);
try {
    DatabaseMetaData dbMetaData = ConnectionUtil.getMetaData(con);
    String productName =
        DatabaseMetaDataUtil.getDatabaseProductName(dbMetaData);
    this.sqlState = getSqlState(productName);
    this.errorCode = getErrorCode(productName);
} finally {
    ConnectionUtil.close(con);
}

こんな感じで判断しました。
# 実際には個別に DBMS 情報クラスにまとめました。


2の方、S2Dao とは別に同じような判断をしていますので、もっと良い方法が
あるかもしれません。

--------------------------------------------------------------
 e-mail: [E-MAIL ADDRESS DELETED]
                                              suga
--------------------------------------------------------------




Seasar-user メーリングリストの案内