我看到了很多类似的问题,但没有找到一些结论性的结论 .
使用JPA时,如果您有@OneToMany关系,则可以指定它级联 REMOVE
操作 . 同时,可以在数据库中指定外键,并在删除键基行时执行操作 .
JPA示例:
@Entity
public class Parent {
@Id
private Long id;
@OneToMany(cascade = {CascadeType.REMOVE})
private List<Child> children;
// getters, setters...
}
@Entity
public class Child {
@Id
private Long id;
@ManyToOne(optional = false)
@JoinColumn(name = parent_id, nullable = false)
private Parent parent;
// getters, setters...
}
在数据库中, Child
表将具有 parent_id
列,其中包含对 Parent
的 id
列的外键约束 .
对于删除时级联的外键约束可能采取的一些操作是 delete
, set to null
和 do nothing
. 这给出了以下场景组合 .
JPA | cascade | no cascade |
| remove | remove |
DB FK | | |
-----------+---------+------------|
delete | A | D |
-----------+---------+------------|
set null | B | E |
-----------+---------+------------|
do nothing | C | F |
-----------+---------+------------+
-
答:在JPA中级联删除对父项的调用,删除父数据库中的子项时,他们有一个外键 .
-
B:在JPA中删除级联,在父级删除时将子表中的外键列设置为空 . @JoinColumn中的
nullable
和@ManyToOne
中的optional
可能需要为true / false . -
C:在JPA中删除级联,在外键移除时在数据库中不执行任何操作 .
-
D:不要在JPA级联删除,在数据库中级联删除父级 .
-
E:不要在JPA中级联删除,在父表删除时将子表中的外键列设置为空 .
-
F:不要在JPA中级联删除,在外键删除时不对数据库执行任何操作 .
所以,对此有疑问 .
Which of these scenarios leads to exceptions? 如果图C会 . 如果通过 EntityManager
删除 Parent
实例,则首先在该实例上进行调用,然后级联到collection属性中的 Child
实例 . 但是,在没有先删除相关子项的情况下尝试从数据库中删除父项会导致外键违规 . 它是否正确?还有其他错误的情况吗? Woud A尝试从已经从基础数据库中删除的持久性中删除实体的问题?
Which leave the EntityManager cache in an inconsistent state with the database? 我认为它是D和E.在这些情况下,您必须自己为子列表中的实例调用 remove()
.
Which setup should you use to enforce data consistency in both the JPA layer and on the database? A会这样做吗?我认为B也可以工作,因为数据库本身会在删除父项时将外键列设置为null(不再违反约束),然后JPA可以删除子实例 .
1 回答
我认为B和E也会导致异常,因为外键字段不可为空 .
使用null更新其值时,将引发异常 .
JPA和数据库之间的
我认为使用A或F将实现它 . 在这两个层面中,将对两个层面采取相同的操作 .