Oracleのエラーコードごとに例外を作る

Oracleのエラーコードごとに例外を作って、エラー発生時、コードに対応する例外を投げさせる。
データベースを更新するとき、事前に整合性をチェックするのはめんどいので、とりあえず更新してみて、整合性に問題があればそのとき対応しようというアプローチ。
デメリットは…スピード?Oracleにエラー判定をさせるので、この設計を嫌がる人はいるかも。

OracleException

Oracle用の例外。一意制約、参照整合性制約以外のエラーはこの例外が投げられる。


package oraerr.exception;

import java.sql.SQLException;

public class OracleException extends RuntimeException {

private String sql = null;

public static OracleException newInstance(String sql, SQLException cause) {
OracleException e = null;

switch (cause.getErrorCode()) {
case 1:
e = new OracleUniqueException(sql, cause);
break;

case 2291:
e = new OracleForeignKeyException(sql, cause);
break;

default:
e = new OracleException(sql, cause);
break;
}

return e;
}

protected OracleException(String sql, SQLException e) {
super("SQL: " + sql, e);

}

public String getSql() {
return sql;
}

public void setSql(String sql) {
this.sql = sql;
}

}

OracleUniqueException

一意制約用の例外。


package oraerr.exception;

import java.sql.SQLException;

public class OracleUniqueException extends OracleException {

OracleUniqueException(String sql, SQLException e) {
super(sql, e);
}

}

OracleForeignKeyException

参照整合性制約用の例外。


package oraerr.exception;

import java.sql.SQLException;

public class OracleForeignKeyException extends OracleException {

public OracleForeignKeyException(String sql, SQLException e) {
super(sql, e);
}

}

実行クラス


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import oraerr.exception.OracleException;
import oraerr.exception.OracleForeignKeyException;
import oraerr.exception.OracleUniqueException;

public class Runner {

public static void main(String[] args) throws ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracleDriver");

// 一意制約
try {
update("insert into DEPT values ('10', 'ACCOUNTING', 'NEW YORK')");
} catch (OracleUniqueException e) {
System.out.println("エラー: 一意制約");
}

// 参照整合性制約
try {
update("insert into emp values (8000, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 99)");
} catch (OracleForeignKeyException e) {
System.out.println("エラー: 参照整合性制約");
}

}

private static int update(String sql) throws OracleException {
Connection conn = null;
PreparedStatement stmt = null;
int count = 0;

try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@//localhost:1521/myoracle", "sugawara",
"sugawara");
stmt = conn.prepareStatement(sql);
count = stmt.executeUpdate();
} catch (SQLException e) {
throw OracleException.newInstance(sql, e);
} finally {
close(null, stmt, conn, sql);
}

return count;
}

private static void close(ResultSet rs, Statement stmt, Connection conn,
String sql) throws OracleException {
try {
if (rs != null) {
rs.close();
}

if (stmt != null) {
stmt.close();
}

if (conn != null) {
conn.close();
}
} catch (SQLException e) {
throw OracleException.newInstance(sql, e);
}
}

}

実行結果は次の通り。


エラー: 一意制約
エラー: 参照整合性制約