[英]JPA: unidirectional many-to-one and cascading delete
Say I have a unidirectional @ManyToOne
relationship like the following:假设我有一个单向的
@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;
}
If I have a parent P and children C 1 ...C n referencing back to P, is there a clean and pretty way in JPA to automatically remove the children C 1 ...C n when P is removed (ie entityManager.remove(P)
)?如果我有一个父 P 和子 C 1 ...C n引用回 P,那么 JPA 中是否有一种干净漂亮的方法可以在删除 P 时自动删除子 C 1 ...C n (即
entityManager.remove(P)
)?
What I'm looking for is a functionality similar to ON DELETE CASCADE
in SQL.我正在寻找的是类似于 SQL 中的
ON DELETE CASCADE
的功能。
If you are using hibernate as your JPA provider you can use the annotation @OnDelete
.如果你使用 hibernate 作为你的 JPA 提供者,你可以使用注解
@OnDelete
。 This annotation will add to the relation the trigger ON DELETE CASCADE
, which delegates the deletion of the children to the database.此注释将向关系添加触发器
ON DELETE CASCADE
,它将子项的删除委托给数据库。
Example:例子:
public class Parent {
@Id
private long id;
}
public class Child {
@Id
private long id;
@ManyToOne
@OnDelete(action = OnDeleteAction.CASCADE)
private Parent parent;
}
With this solution a unidirectional relationship from the child to the parent is enough to automatically remove all children.使用此解决方案,从子级到父级的单向关系足以自动删除所有子级。 This solution does not need any listeners etc. Also a JPQL query like
DELETE FROM Parent WHERE id = 1
will remove the children.此解决方案不需要任何侦听器等。此外,像
DELETE FROM Parent WHERE id = 1
这样的 JPQL 查询将删除子级。
Relationships in JPA are always unidirectional, unless you associate the parent with the child in both directions. JPA 中的关系始终是单向的,除非您在两个方向上将父级与子级关联起来。 Cascading REMOVE operations from the parent to the child will require a relation from the parent to the child (not just the opposite).
从父级到子级的级联 REMOVE 操作将需要从父级到子级的关系(而不仅仅是相反)。
You'll therefore need to do this:因此,您需要这样做:
@ManyToOne
relationship to a bi-directional @ManyToOne
, or a unidirectional @OneToMany
.@ManyToOne
关系更改为双向@ManyToOne
或单向@OneToMany
。 You can then cascade REMOVE operations so that EntityManager.remove
will remove the parent and the children.EntityManager.remove
将删除父项和子项。 You can also specify orphanRemoval
as true, to delete any orphaned children when the child entity in the parent collection is set to null, ie remove the child when it is not present in any parent's collection.orphanRemoval
指定为 true,以在父集合中的子实体设置为 null 时删除任何孤立的子实体,即当子实体不存在于任何父集合中时删除子实体。ON DELETE CASCADE
.ON DELETE CASCADE
。 You'll need to invoke EntityManager.clear()
after calling EntityManager.remove(parent)
as the persistence context needs to be refreshed - the child entities are not supposed to exist in the persistence context after they've been deleted in the database.EntityManager.remove(parent)
EntityManager.clear()
之后调用 EntityManager.clear(),因为需要刷新持久性上下文 - 子实体在数据库中被删除后不应该存在于持久性上下文中。Create a bi-directional relationship, like this:创建双向关系,如下所示:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
private Set<Child> children;
}
I have seen in unidirectional @ManytoOne, delete don't work as expected.我在单向@ManytoOne 中看到,删除不能按预期工作。 When parent is deleted, ideally child should also be deleted, but only parent is deleted and child is NOT deleted and is left as orphan
删除父级时,理想情况下也应删除子级,但仅删除父级,不删除子级并保留为孤儿
Technology used are Spring Boot/Spring Data JPA/Hibernate使用的技术是 Spring Boot/Spring Data JPA/Hibernate
Sprint Boot : 2.1.2.RELEASE冲刺启动:2.1.2.RELEASE
Spring Data JPA/Hibernate is used to delete row .eg Spring Data JPA/Hibernate 用于删除行.eg
parentRepository.delete(parent)
ParentRepository extends standard CRUD repository as shown below ParentRepository extends CrudRepository<T, ID>
ParentRepository 扩展标准 CRUD 存储库,如下所示
ParentRepository extends CrudRepository<T, ID>
Following are my entity class以下是我的实体类
@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;
}
用这种方式只删除一侧
@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;
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
Given annotation worked for me.给定注释对我有用。 Can have a try
可以试一试
For Example :-例如 :-
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;
}
您不需要使用双向关联而不是代码,只需将 CascaType.Remove 作为属性添加到 ManyToOne 注释,然后使用 @OnDelete(action = OnDeleteAction.CASCADE),它对我来说很好用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.