コンテナー管理トランザクション(JBoss AS 6.1.0.Final)のプロバイダーとしてHibernateでJPAを使用しています。
アプリに特定の例外階層があり、あらゆる状況で何をすべきかを定義できるため、きめ細かい例外処理を実装しようとしています。それで、私は何時間も調査してきましたが、例外処理は常に「明確にするために」省略されているか、例外eを処理する単純なtry-catchブロックであるため、ドキュメントはあいまいで、例はやや生々しいものです。
たとえば、次のコードを考えてみましょう。
public void deleteCompany(ICompany company) throws MyException1, MyException2 {
if(entityManager != null){
if(company !=null) {
try {
ICompany companyReference= entityManager.getReference(Company.class, company.getId());
entityManager.remove(managedCompany);
entityManager.flush();
} catch(EntityNotFoundException companyDoesNotExist) {
//Wrap & Throw
}
} else {
throw new MyException1("An error occurred while attempting to save a null instance of a company");
}
} else {
throw new MyException2("The entity manager instance is null");
}
}
ここでスタックしているため、catchブロックは空白です...ユーザーが存在しないレコードを削除しようとしていることをシステムに警告するために、どの例外をキャッチする必要があるかわかりません。
私の具体的な質問は、そのキャッチブロックでHibernateの例外をキャッチできますか、それともJPAの例外をキャッチする必要がありますか?JPAがプロバイダーの例外をラップしていると主張する情報源をいくつか見つけましたが、それは私には奇妙に聞こえます。また、flush()メソッドを呼び出すと、データベースアクセスと操作の例外をキャッチできることがわかりました。これは、トランザクションがコンテナーによって管理され、deleteCompanyを呼び出した後にコミットメントがさらにステップアップするためです。
ありがとうございました。
編集: @ApplicationException(rollback = true)で注釈が付けられた独自の例外でキャッチした例外をラップしているので、それらを再度スローして、より明確に処理できます。
編集2:コードを更新しました。削除前のマージは、データベースにない場合でも会社を存続させ、削除が毎回成功する原因になります。現在、例外がスローされており、Perceptionによって提案されているように、JPA例外をキャッチするさまざまな状況でどのように動作するかをテストしています。
編集3:今は機能しています!、そのマージ呼び出しのためにエラーが部分的に私のコードにあったことがわかりました。最初に参照を取得し、後で削除を試みると、トリックが実行されます。これにより、EntityNotFoundExceptionをキャッチし、ラップして、再度スローすることができました。