2011-08-25 10 views
63

を削除カスケードは、私は次のような一方向の@ManyToOne関係があるだろう:私は親Pと子供C をお持ちの場合はJPA:単方向へ-1対多および

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 
} 

@Entity 
public class Child implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @ManyToOne 
    @JoinColumn 
    private Parent parent; 
} 

を... CバックPへの参照 N、自動的に子供C を削除するにはJPAで清潔できれいな方法があります... C N Pが削除された(すなわちentityManager.remove(P))?

私が探しているのは、SQLのON DELETE CASCADEに似た機能です。

+1

「子」のみが「親」への参照を持っていても(参照が単方向である場合)、「子」のリストに「@OneToMany」マッピングを追加し、「カスケード= ALL」 '属性を'親 'に設定しますか?私はJPAが、1面だけが参照を保持することさえ困難であると解決すべきだと考えます。 – kvDennis

+1

@kvDennisでは、多面を片面にしっかりと結合したくない場合があります。例えば。セキュリティ権限が透過的なACLのような設定では、「アドオン」 – Bachi

答えて

56

JPAのリレーションシップは、両方向で親を子に関連付ける場合を除き、常に一方向です。親から子へのREMOVE操作のカスケード接続には、親から子へのリレーションが必要です(反対側だけでなく)。

そのため、これを実行する必要があります

  • のどちらかが、@ManyToOne双方向、または単方向@OneToManyに一方向の@ManyToOne関係を変更します。その後、削除操作をカスケードして、EntityManager.removeが親と子を削除します。 orphanRemovalをtrueに指定して、親コレクション内の子エンティティがnullに設定されている場合に孤立した子を削除することができます。つまり、親コレクションに存在しない場合は子を削除します。
  • または、子テーブルの外部キー制約をON DELETE CASCADEと指定します。永続コンテキストをリフレッシュする必要があるため、EntityManager.remove(parent)を呼び出してからEntityManager.clear()を呼び出す必要があります。子エンティティは、データベース内で削除された後で永続コンテキストに存在するはずです。
+4

はJPAアノテーションでNo2を実行する手段ですか? – user2573153

+2

Hibernate xmlマッピングでNo2を行うにはどうしたらいいですか? – arg20

+0

以下の答えはあなたより良いです – Enerccio

11

このように、双方向の関係を作成します。

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) 
    private Set<Child> children; 
} 
+0

大きな子供のセットでの操作には時間がかかりますので、JPAでは双方向の関係がひどいです – Enerccio

-1

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

注釈が私のために働い考えます。例については

: -

 public class Parent{ 
      @Id 
      @GeneratedValue(strategy=GenerationType.AUTO) 
      @Column(name="cct_id") 
      private Integer cct_id; 
      @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true) 
      @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
      private List<Child> childs; 
     } 
      public class Child{ 
      @ManyToOne(fetch=FetchType.EAGER) 
      @JoinColumn(name="cct_id") 
      private Parent parent; 
    } 
39

あなたは注釈@OnDeleteを使用することができ、あなたのJPAプロバイダとして休止状態を使用している場合。このアノテーションは、トリガーのON DELETE CASCADEをリレーションシップに追加し、子の削除をデータベースに委任します。

例:このソリューションでは

public class Parent { 

     @Id 
     private long id; 

} 


public class Child { 

     @Id 
     private long id; 

     @ManyToOne 
     @OnDelete(action = OnDeleteAction.CASCADE) 
     private Parent parent; 
} 

親の子からの一方向の関係は、自動的にすべての子を除去するのに十分です。この解決策ではリスナーなどは必要ありません。親から削除するid = 1は子供を削除します。

+0

これは@ManyToOneのデザインを変更しないと完璧な解決策です。 –

+0

これはすばらしい答えです。これは重要な機能です。 – Yoi

+2

このように動作させることはできません。特定のバージョンのHibernateやこれ以上の詳細な例がありますか? – Mardari