반응형
관계형 DB의 데이터를 삭제할 때 사용하는 @OnDelete와 cascade = CascadeType.REMOVE의 차이를 알아보자!
@OnDelete
- DDMS 레벨에서 작동
- @OnDelete(action = OnDeleteAction.CASCADE)
- DDL 생성시 cascade 제약 조건이 생성 됨.
여기서 DDL이란 Data Definition Language로 데이터 베이스를 정의하는 언어이며, CREATE, ALTER, DROP, TRUNCATE를 말한다.
casecade=CascadeType.REMOVE
- JPA 레벨에서 작동
- JPA가 부모 엔티티를 삭제할 때 연관된 자식 데이터에 대한 DELETE 쿼리를 실행 함
본인의 경우 부모와 자식의 1:N 관계일 때 아래 요구사항을 충족시켜야 했다.
요구사항 1 : 부모 엔티티를 삭제 할 경우 자식 엔티티는 모두 삭제되어야 한다.
요구사항 2 : 자식 엔티티를 삭제해도 부모 엔티티는 삭제되면 안된다.
1. cascade = CascadeType.REMOVE를 설정할 경우
자식 엔티티를 삭제하는 쿼리가 먼저 실행되고, 그 다음 부모 엔티티를 삭제하는 쿼리가 실행 된다.
그리고 자식 엔티티 한 건을 삭제 하려고 하면 부모 테이블에 연관되어 있는 데이터가 존재 하므로 아래와 같이 에러가 발생한다.
(부모와 연관된 자식이 한건이라면 이 에러가 발생하지 않는다.)
오류: "부모" 테이블의 자료 갱신, 삭제 작업이 "fk7tttuo3u7xbkpq73oyc128uhl" 참조키(foreign key) 제약 조건 - "자식" 테이블 - 을 위반했습니다
Detail: (req_id)=(904a90be-8055-413e-b1f8-871e59287dbf) 키가 "자식" 테이블에서 여전히 참조됩니다.
또한 부모 엔티티를 삭제하려고 해도 아래와 같은 에러가 발생한다.
오류: "부모" 테이블의 자료 갱신, 삭제 작업이 "fk7tttuo3u7xbkpq73oyc128uhl" 참조키(foreign key) 제약 조건 - "자식" 테이블 - 을 위반했습니다
Detail: (req_id)=(34accdf4-3fbe-4b5e-8d97-85ff9e6b9bc0) 키가 "자식" 테이블에서 여전히 참조됩니다.
2. 둘다 설정할 경우
위와 같은 에러는 발생하지 않지만 자식 엔티티 하나만 삭제해도 부모와 관련있는 모든 자식 엔티티까지 삭제 된다.
결론 : @OnDelete(action= OnDeleteAction.CASCADE)만 설정하여 위 요구사항을 충족시켰다!
@ManyToOne(fetch = FetchType.LAZY)
@OnDelete(action= OnDeleteAction.CASCADE)
@JoinColumn(name = "REQ_ID", referencedColumnName = "REQ_ID", columnDefinition ="VARCHAR(36)")
private Parent parent;
728x90
반응형
'개발 > JPA' 카테고리의 다른 글
[JPA] Specification을 이용하여 쿼리 조건 처리하기 - 외래키 (2) | 2022.01.07 |
---|---|
[JPA] 복합키, 외래키 Entity 설정하기(@IdClass를 사용하여 식별관계 매핑) (1) | 2021.12.23 |
[JPA] 데이터를 insert 하기 전에 select하는 이유 (0) | 2021.12.02 |
[JPA] @OneToMany - 자식 테이블(관계 Entity)의 데이터를 상황에 따라 가져오기 (0) | 2021.11.26 |
댓글