私が現在取り組んでいるシステムでは、関係のないオブジェクトは自由に削除できますが、論理的に削除する必要があるというポリシーがあります。履歴情報が削除されないようにするためのものです。Hibernate:削除の前に外部キー制約違反をチェックしますか?
基本的に、私がやっていることは、オブジェクトのキーが現在別のテーブルに存在するかどうかを判断することでした。そうでない場合は、単にdelete()を呼び出します。それ以外の場合は、論理的な削除を示すプロパティを設定し、update()を呼び出します。
私はSpringトランザクション管理を使用していますので、できるだけセッション自体を混乱させようとしています。 Hibernateの例外は致命的で
@Transactional
public void deleteObject(SomeEntity object)
{
//try to delete
this.someEntityDAO.delete(object);
try //force foreign key constraint check
{
this.someEntityDAO.flush();
}
catch (ConstraintViolationException e)
{
//reload object
object= this.someEntityDAO.loadById(object.getId());
//save as inactive instead of deleting
object.setActive(false);
this.someEntityDAO.update(object);
}
}
ので、これは完全に信頼できない(それが動作するにもかかわらず):私の最初のアプローチは、最初に動作するように見えますが、あなたはそれが大きな欠陥を持っていることがわかります。実際に操作を実行することなく(したがってセッションを無効にすることなく)、制約のために削除が失敗するかどうかをテストできる一種の「ピーク」操作を行う方法があるかどうか疑問に思っていました。私が考えることができるのは、関連する各テーブルを手動でチェックしてIDが存在するかどうかを確認することですが、これは非常に退屈で、多くの関係があるテーブルではエラーが発生しやすくなります。可能であれば、データベースに既に存在する制約を活用したいと思います。
はい削除する前にSQlを直接実行するか、これらの制約をチェックするために追加のHibernateコードを追加できます。物事は、エンティティの関係のすべてを追跡し、より多くの関係が追加されればコードに戻る必要があるので、私はそれをやりたいとは思わなかったということです。私が示唆したようにそれを行うには、DB上で制約を適切に設定して、データベースがある時点で変更されたかどうかにかかわらず、そのコードに再度アクセスしないでください。 – JayPea
@JayPea "私が提案したように私がやる方法があれば、DB上で制約を適切に設定して、データベースがある時点で変更されたかどうかにかかわらず、そのコードに戻ってはいけません。 "データベース設計が変更されたことを意味するものではないと仮定した場合、YESを実行することができます!とする必要があります。 ...参照整合性は非常に重要なことです。それを学び、それを使用して、あなたの仕事に力を与えるようにしてください! (私は、Postgres、Informix、Ingres、Oracle、DB2、Sybaseなどと協力しています。すべての深刻なリレーショナルデータベースシステムには、必要な機能が組み込まれています)。 –