109

次のような一方向 @ManyToOneの関係があるとします。

@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;  
}

親Pと子C1 ... C nがPを参照している場合、JPAには、Pが削除されたときに子C 1 ... C nを自動的に削除するクリーンできれいな方法がありますか(つまりentityManager.remove(P))?

私が探しているのは、ON DELETE CASCADESQLと同様の機能です。

4

7 に答える 7

114

JPA プロバイダーとして hibernate を使用している場合は、アノテーションを使用できます@OnDelete。この注釈は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;
}
     

このソリューションでは、子から親への一方向の関係で、すべての子を自動的に削除できます。このソリューションはリスナーなどを必要としません。また、JPQL クエリのようなものDELETE FROM Parent WHERE id = 1は子を削除します。

于 2016-07-21T04:59:03.870 に答える
77

親と子を双方向で関連付けない限り、JPA の関係は常に一方向です。親から子への REMOVE 操作のカスケードには、親から子へのリレーションが必要です (反対だけではありません)。

したがって、これを行う必要があります。

  • 単方向の@ManyToOne関係を双方向@ManyToOneまたは単方向に変更し@OneToManyます。その後、REMOVE 操作をカスケードしてEntityManager.remove、親と子を削除できます。orphanRemovalまた、親コレクションの子エンティティが null に設定されている場合に孤立した子を削除するには、true を指定できます。つまり、親のコレクションに存在しない子を削除します。
  • または、子テーブルの外部キー制約を として指定しますON DELETE CASCADEEntityManager.clear()永続コンテキストを更新する必要があるため、呼び出し後に呼び出す必要があります。EntityManager.remove(parent)子エンティティは、データベースで削除された後、永続コンテキストに存在することは想定されていません。
于 2011-08-26T05:06:52.183 に答える
15

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

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
    private Set<Child> children;
}
于 2012-06-18T01:28:19.100 に答える
2

一方向の @ManytoOne で見たことがありますが、削除が期待どおりに機能しません。親が削除されると、理想的には子も削除されるべきですが、親のみが削除され、子は削除されず、孤立したままになります

使用されるテクノロジーは、Spring Boot/Spring Data JPA/Hibernate です。

スプリント ブート: 2.1.2.RELEASE

Spring Data JPA/Hibernate を使用して行を削除します。

parentRepository.delete(parent)

ParentRepository は、以下に示すように標準の CRUD リポジトリを拡張します ParentRepository extends CrudRepository<T, ID>

以下は私のエンティティクラスです

@Entity(name = “child”)
public class Child  {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne( fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = “parent_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Parent parent;
}

@Entity(name = “parent”)
public class Parent {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable = false, length = 50)
    private String firstName;


}
于 2019-02-11T15:57:03.810 に答える