JPAの実装としてEclipseLink(2.3.2)を利用しているのですが、とある画面の仕様で、単純な保存失敗だけではなく、一意制約で保存失敗したよ、というのまで拾う必要があって、まぁ、それはそんなことは簡単じゃろいと思ったのですが…これがなかなか…(-_-;
調べると同じことトライしてる人が結構いた…(^^;
一番上のが自分とほぼ同じ悩みで、INSERT処理はEJBを経由しているため、まずEJBExceptionになっていて…例外を辿っていくと
- org.eclipse.persistence.exceptions.DatabaseException
- com.microsoft.sqlserver.jdbc.SQLServerException
となって「制約 'HogeHoge_PKC' の PRIMARY KEY 違反。オブジェクト 'dbo.Hoge' には重複したキーを挿入できません。」と。
Stackoverflowの情報みると、本来JPAの仕様ではEntityExistExceptionを返すようですが、EclipseLinkで(バグなのかよくわからないですが)拾えなかったです…なんか自分ので変なとこあるのかなぁ。ただ、Stackoverflowでも同じようなこと言ってるので、やはりそうなのかなと。
ふむー。そうなると選択肢は
これは厳密なチェックではないのでやりたくない
- getCause()で辿っていってSQLServerExceptionのメッセージで判断
こういうことやってる情報をみつけたけど、これは微妙…(-_-;メッセージで判断って…
あとDBベンダ固有の例外を取得するのはあまりなぁ、みたいな情報もチラホラあって、まあ確かに…と思ったり。
で、色々調べましたが、結局最終的には、getCause()で辿って、やはりSQLServerExceptionDatabaseExceptionをみて
DatabaseException dex = (DatabaseException) ex.getCause().getCause();
dex.getDatabaseErrorCode();
dex.getErrorCode();
みたいにコードで判定しようかなと。
コード細かく調べたいと思ってMSDNみたけど…
http://msdn.microsoft.com/ja-jp/library/ms378831(v=sql.105).aspx
どこに情報あるんすか…。
2013/4/25 追記
今日見直したらDatabaseExceptionはEclipseLinkの例外でしたので取り消し線で修正しましたm(_ _)m
あとgetDatabaseErrorCode()で取得できる「2627」のDBエラーコードはここにありました。
http://msdn.microsoft.com/ja-jp/library/ms152467(v=sql.105).aspx
getErrorCodeはEclipseLinkでSQLExceptionを示す意味のようです。
http://www.eclipse.org/eclipselink/api/1.0/constant-values.html#org.eclipse.persistence.exceptions.DatabaseException.SQL_EXCEPTION
明日この辺りのコードをもう少し詳しく調べてみて、これを使おうかなと思います。
今まで何とかDBの差異を意識せずに(Native Queryとか使わず)作ってきましたが、ここは諦めました。
てか、EclipseLinkでちゃんとEntityExistsExceptionが取れて欲しい。。。