说我有一个单向 @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被移除时(即entityManager.remove(P)
),子C 1 ... C n ?
我正在寻找的功能类似于SQL中的ON DELETE CASCADE
。
答案 0 :(得分:72)
如果您使用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;
}
使用此解决方案,从孩子到父母的单向关系足以自动删除所有孩子。此解决方案不需要任何侦听器等。 DELETE FROM Parent WHERE id = 1 之类的查询也将删除子节点。
答案 1 :(得分:66)
JPA中的关系始终是单向的,除非您在两个方向上将父级与子级相关联。从父母到孩子的级联REMOVE操作将需要从父母到孩子的关系(而不仅仅是相反的)。
因此,您需要这样做:
@ManyToOne
关系更改为双向@ManyToOne
或单向@OneToMany
。然后,您可以级联REMOVE操作,以便EntityManager.remove
将删除父项和子项。您还可以将orphanRemoval
指定为true,以便在父集合中的子实体设置为null时删除任何孤立子项,即删除子项在任何父项集合中不存在时的子项。ON DELETE CASCADE
。在调用EntityManager.clear()
之后,您需要调用EntityManager.remove(parent)
,因为需要刷新持久性上下文 - 在数据库中删除后,子实体不应该存在于持久性上下文中。 / LI>
答案 2 :(得分:13)
创建双向关系,如下所示:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
private Set<Child> children;
}
答案 3 :(得分:0)
我在单向@ManytoOne中看到过,删除无法正常工作。 删除父级后,理想情况下也应删除子级,但仅删除父级,不删除子级,而将其保留为孤儿
使用的技术是Spring Boot / Spring Data JPA / Hibernate
Sprint引导:2.1.2。释放
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;
}
答案 4 :(得分:0)
使用这种方式仅删除一侧
@ManyToOne(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
// @JoinColumn(name = "qid")
@JoinColumn(name = "qid", referencedColumnName = "qid", foreignKey = @ForeignKey(name = "qid"), nullable = false)
// @JsonIgnore
@JsonBackReference
private QueueGroup queueGroup;
答案 5 :(得分:-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;
}
答案 6 :(得分:-1)
您不需要使用双向关联而不是代码,只需将CascaType.Remove作为属性添加到ManyToOne批注中,然后使用@OnDelete(action = OnDeleteAction.CASCADE),对于我。