1

PostgreSQLで(Hibernateを使用して)次のことをしたい:

 ALTER TABLE fruits ADD CONSTRAINTS id ON DELETE CASCADE;

明らかに、上記のコードは機能しないため、正しいステートメントを探しています。

それができない場合は、次のようにします。

テーブルにたくさんのデータがありますfruits。のidフィールドはfruits、テーブルによって外部キーとして使用されますgrapes。の特定の行を削除する必要がありfruits、削除をカスケードして、指定された のgrapesすべてのエントリを削除します。それ、どうやったら出来るの?grapesid

delete from fruits where id = 1 cascade; 

注: の対応するデータを結合して削除したくありませんgrape。これはほんの一例です。実際のアプリケーションでは、多数のテーブルが に依存していfruitsます。

私は Hibernate を使用しているので、delete ステートメントを使用する場合、Hibernate はそれを助けることができますか?
または、PostgreSQL の情報スキーマまたはシステム カタログでこれを行うことはできますか?

4

4 に答える 4

4

あなたが説明するのは、オプションを使用した教科書の外部キー制約です。ON DELETE CASCADE

SQLではgrapesシナリオでテーブルを作成するときに暗黙的に作成できます。

CREATE TABLE grapes (
  grape_id int PRIMARY KEY
  fruit_id int REFERENCES fruits(fruit_id) ON DELETE CASCADE
  );

または、後で追加することもできます。

ALTER TABLE grapes
ADD CONSTRAINT grapes_fruit_id_fkey FOREIGN KEY (fruit_id)
REFERENCES fruits (fruit_id) ON DELETE CASCADE;

そのためにシステムカタログを直接編集することはありません。ほとんど編集しません。これが、上記のようなDDLステートメントの目的です。

外部キー制約には、参照される列(このfruits.fruit_id場合)に一意のインデックスまたはプライマリインデックスが必要であり、参照整合性が適用されることに注意してください。

于 2012-07-20T16:28:33.950 に答える
1

これは一方向の親子関係であり、親での変更を子にカスケードする必要がありますが、その逆は必要ありません。注釈を使用すると、これを実現できます。fruitsエンティティ内:

@Cascade(value = { org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
@OneToMany(fetch = FetchType.LAZY, mappedBy = "fruit")
public Set<Grape> getGrapes() {
    return grapes;
}

「ブドウ」エンティティで:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fruit_id")
public Fruit getFruit() {
    return fruit;
}

親を更新または削除するfruitと、変更は自動的にgrape子にカスケードされます。

于 2012-07-18T02:54:09.183 に答える
1

私は答えを見つけました:

    //in Fruit object
    @OneToMany(mappedBy = "fruit", orphanRemoval=true)
    private List<Grape> grapes;

   //in Grape object
   @OneToOne
   private Fruit fruit;
于 2012-07-23T05:10:47.840 に答える
0

動機

これは私にはうまくいきませんでした、私は設定しました

<property name="show_sql">true</property> 

出力には のようなものは何も表示されませんでした...ON DELETE CASCADE...

私のために働いた別の解決策を見つけました:

著者用のクラスと著者の本用のクラスがあり、(休止状態、SQL クエリなどを介して) 著者を削除するたびにすべての本を自動削除したいとしますが、(常に) 削除できない理由があるとします。 session.delete()。

多分:

session.createSQLQuery("DELETE FROM author").executeUpdate();

解決

したがって、作成者クラスは次のようになります。

@Entity
@Table(name = "author")
public class Author {

   @Id
   @GeneratedValue(generator = "increment")
   @GenericGenerator(name = "increment", strategy = "increment")
   @Column(name = "ID")
   private Integer id;

   @Column(name = "NAME")
   private String name;

   @OneToMany(mappedBy = "author")
   private Set<Book> books;
...

クラスブックは次のようになります。

@Entity
@Table(name = "book")
public class Book {

   @Id
   @GeneratedValue(generator = "increment")
   @GenericGenerator(name = "increment", strategy = "increment")
   @Column(name = "ID")
   private Integer id;

   @Column(name = "TITLE")
   private String title;

   @ManyToOne
   @JoinColumn(name = "AUTHOR_ID", foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID"))
   private Author author;
...

トリックは、を使用して自分で外部キー制約に名前を付けることです

foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID")

そして追加

<property name="hibernate.hbm2ddl.import_files">update.sql</property>

hibernate.cfg.xmlに追加します( hibernate.hbm2ddl.autoを忘れないでください)。update.sqlには、テーブル制約の更新が含まれます

ALTER TABLE `book` DROP FOREIGN KEY `FK_BOOK_author_AUTHOR_ID`; 
ALTER TABLE `book` ADD CONSTRAINT `FK_BOOK_author_AUTHOR_ID` FOREIGN KEY (`AUTHOR_ID`) REFERENCES `author`(`ID`) ON DELETE CASCADE;

そのため、hibernate は制約の名前を認識しているため、常に制約をドロップ/変更できます。@Cascade 設定も確認する必要があります。また、セッションでオブジェクトの削除を処理する方法について戦略を実装する必要があります。

于 2014-10-17T15:22:42.777 に答える