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