JPA:单向多对一和级联删除

说我有一个单向的 @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和子C 1 … C n引用回P,那么在JPA中有一个干净漂亮的方法来在P被移除时自动删除子C 1 … C n (即entityManager.remove(P) )?

我在找的是一个类似于SQL中的ON DELETE CASCADE的function。

JPA中的关系始终是单向的,除非您在两个方向上将父项与子项相关联。 将父级的REMOVE操作级联到子级将需要从父级到子级的关系(而不仅仅是相反)。

您因此需要这样做:

  • 或者,将单向@ManyToOne关系更改为双向@ManyToOne或单向@OneToMany 。 然后可以级联REMOVE操作,以便EntityManager.remove将删除父项和子项。 您还可以指定orphanRemoval为true,以便在父集合中的子实体设置为null时删除任何孤儿,也就是说,如果该子实体不存在于父集合中,则删除它。
  • 或者,将子表中的外键约束指定为ON DELETE CASCADE 。 在调用EntityManager.remove(parent) EntityManager.clear()之后,需要调用EntityManager.clear() ,因为持久化上下文需要刷新 – 子实体在数据库中被删除之后不应该存在于持久化上下文中。

如果您使用hibernate作为您的JPA提供程序,则可以使用注释@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; } 

有了这个解决scheme,从孩子到父母的单向关系足以自动移除所有的孩子。 这个解决scheme不需要任何监听器等。另外,像DELETE FROM Parent WHERE id = 1这样的查询将删除这些子项。

创build一个双向关系,如下所示:

 @Entity public class Parent implements Serializable { @Id @GeneratedValue private long id; @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) private Set<Child> children; } 

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