2011-12-08 16 views
1

使用cascade = CascadeType.REMOVEテーブルの生成中にhibernateは 'ON DELETE CASCADE'を追加しません。これは正しい行動ですか?親オブジェクトでem.remove()を実行しても問題ありませんが、HQL経由で一括削除を実行しようとするとエラーが発生します。Hibernateは 'カスケード削除時'を追加しません

のPostgreSQL 9.1は、Hibernate 4.0.0.CR7

答えて

7

あなたが探しているのは、hibernate(DDL文)によるスキーマ生成に影響する@OnDeleteアノテーションです。ただし、この注釈は、データベースの外部キー定義にON DELETE CASCADE句が存在しない場合に、バルク削除の場合に参照元のエンティティ/行に削除をカスケードしません。

@OneToMany 
@OnDelete(action=OnDeleteAction.CASCADE) 
public Set<Stuff> getStuff() { 
    return stuff; 
} 
+0

私は夢中になります。 @OnDeleteは@OneToManyでは動作しますが、@OneToOneでは動作しません!さらに、移植性がありません。 'cascade = CascadeType.REMOVE'のとき、他のORMは' ON DELET CASCADE'を適用しますか? – Alf

+0

@tschoどのように1対1のマッピングのためにこれを達成するためのアイデア? – Sikorski

+0

@Sikorski私は '@ OneToOne'マッピングを使ってうまく動作しました。休止状態の使用4.2.1。 –

2

これは正常な動作です。カスケードアノテーションは、削除をカスケードするようにHibernateに指示します。これを行うにはデータベースではなくHibernateの責任があります。

バルク削除クエリはセッションを完全にバイパスし、エンティティはアノテーションをカスケードします。あなたがそれらを使用することを選択すると、カスケード削除を処理する必要があります。

1

あなたが言及している 'ON DELETE CASCADE'機能はデータベーストリガーです。 Hibernateはトリガーを設定しません。注釈を使用して、Hibernateは、標準のSELECTおよびDELETEステートメントを使用して子オブジェクトの削除を管理します。デバッグをオンにすると、これが表示されます。最初にhibernateを使用すると、これは恐ろしく非効率的に見えます。それは、あなたが参照しているHQLを介して一括削除を使用するように見えるときです。

テーブル生成では、トリガーなどのデータベース固有の機能は追加されません。あなたは子オブジェクトを削除できるようにしたい場合はHQLを使用する場合は、あなたが実行する独自の「クリーンアップ」のコードを記述する必要がありので、あなたの要件に応じて

@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true) 
private List<Case> cases = new ArrayList<Case>(); 

は直接それは、カスケードロジックをバイパスし、このような何かを試してみてください定期的にorhapnsなどをクリーンアップします。効率のために、私はこの目的のためにストアドプロシージャを書くことにしました。

代わりに、削除する親オブジェクトのコレクションを取得し、それらを1つずつループすることができます。あなたのコレクションが大きい場合、これは効率的ではありませんが、少なくともあなたの恩赦で定義したようにカスケードします。

関連する問題