我看到很多类似的问题,但还没有找到将结合在一起的结论。级联在JPA @OneToMany中删除与数据库级联外键删除
使用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中级联删除,将父表中的外键列设置为null,在父删除的数据库中为空。在这种情况下,@JoinColumn中的
nullable
和/或@ManyToOne
中的optional
可能需要为true/false。 - C:Cascade在JPA中删除,在数据库中不做任何外键删除。
- D:不要在JPA中级联删除,在数据库中级联删除父级。 E:不要在JPA中级联删除,将父表中的子表中的外键列设置为在父删除中的数据库中为空。 F:不要级联删除JPA中的数据库,在外键删除时什么也不做。
所以,关于这个问题。
以下哪种情况会导致异常?如果图C会。如果通过EntityManager
删除Parent
实例,则该调用首先在该实例上完成,然后级联到collection属性中的Child
实例。但是,在没有首先删除相关子项的情况下尝试从数据库中删除父项会导致外键违规。它是否正确?是否有其他错误的情况? Woud试图从已经从基础数据库中删除的持久性中删除实体时遇到问题?
这使EntityManager缓存处于与数据库不一致的状态吗?我认为它是D和E.在这些情况下,您必须自己为子列表中的实例调用remove()
。
您应该使用哪种设置来强制实现JPA层和数据库中的数据一致性?请问A会这样做吗?我认为B也可以工作,因为数据库本身会在删除父项时将外键列设置为空(不再违反约束),然后JPA可以删除子实例。