[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 メーリングリストの案内