본문 바로가기
개발/JPA

[JPA] @OnDelete VS cascade = CascadeType.REMOVE

by zuzuu 2021. 12. 13.
반응형

관계형 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
반응형

댓글