비슷한 질문이 많지만 결정적인 결론을 얻지 못했습니다.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 | -----------+---------+------------+
- A : 계단식, JPA에서 부모에 전화를 제거 그들이에 외래 키가 부모 행의 삭제에 데이터베이스에 아이들을 삭제합니다.
- B : JPA에서 계단식 제거, 상위 삭제시 데이터베이스에서 하위 테이블의 외래 키 열을 null로 설정하십시오. @JoinColumn의
nullable
및/또는optional
의@ManyToOne
은 아마도이 경우 true/false이어야합니다. - C : JPA에서 계단식 제거, 외래 키 제거시 데이터베이스에서 아무 것도 수행하지 않음.
- D : JPA에서 캐스케이드 제거를 수행하지 말고 데이터베이스에있는 부모의 계단식 삭제를 수행하지 마십시오.
- E : JPA에서 제거를 계단식으로하지 마십시오. 상위 삭제시 데이터베이스에서 하위 테이블의 외래 키 열을 null로 설정하십시오.
- F : JPA에서 제거를 계단식으로하지 마십시오. 외래 키 제거에서 데이터베이스를 수행하지 마십시오.
이에 대한 질문입니다.
다음 중 어떤 시나리오가 예외로 연결됩니까? 그림 C의 경우. EntityManager
을 통해 Parent
인스턴스를 제거하면 해당 인스턴스에서 호출이 완료된 후 콜렉션 등록 정보의 Child
인스턴스로 계단식 연결됩니다. 그러나 관련 아이를 먼저 제거하지 않고 데이터베이스에서 상위 항목을 제거하려고하면 외래 키 위반이 발생합니다. 이 올바른지? 다른 오류 시나리오가 있습니까? Woud 기본 DB에서 이미 제거 된 엔티티를 제거하려고 할 때 문제가 발생합니까?
데이터베이스와 일치하지 않는 상태로 EntityManager 캐시를 남겨 둡니까? 저는 D와 E라고 생각합니다. 이러한 경우에는 자식 목록의 인스턴스에 대해 remove()
으로 직접 전화해야합니다.
JPA 계층과 데이터베이스 모두에서 데이터 일관성을 유지하기 위해 사용해야하는 설정은 무엇입니까? 트릭을 할 수 있습니까? 데이터베이스 자체가 부모 (더 이상 제약 조건을 위반하지 않음)를 삭제할 때 외래 키 열을 null로 설정하고 JPA가 하위 인스턴스를 제거 할 수 있기 때문에 B도 작동 할 수 있다고 생각합니다.