読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

EclipseLinkで一意制約の例外を拾ってみたけど…

JPA SQL Server 2008 R2 EclipseLink

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でも同じようなこと言ってるので、やはりそうなのかなと。

ふむー。そうなると選択肢は

  • INSERT前に重複するキーがあるかチェックする

これは厳密なチェックではないのでやりたくない

  • getCause()で辿っていってSQLServerExceptionのメッセージで判断

こういうことやってる情報をみつけたけど、これは微妙…(-_-;メッセージで判断って…

あとDBベンダ固有の例外を取得するのはあまりなぁ、みたいな情報もチラホラあって、まあ確かに…と思ったり。

で、色々調べましたが、結局最終的には、getCause()で辿って、やはりSQLServerExceptionDatabaseExceptionをみて

DatabaseException dex = (DatabaseException) ex.getCause().getCause();
dex.getDatabaseErrorCode(); //2627がとれる
dex.getErrorCode(); //4002がとれる

みたいにコードで判定しようかなと。

コード細かく調べたいと思って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が取れて欲しい。。。

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村