JPA 특정 엔티티 삭제시 연관된 엔티티도 함께 삭제하기

2022. 7. 12. 18:08·Stack/Spring

프로젝트에서 하나의 엔티티를 삭제했을 때 이 엔티티와 연관된 다른 엔티티는 어떻게 될까?? 정답은 그 엔티티의 외래 키로 연결된 엔티티에서는 부모 엔티티가 없기 때문에 데이터베이스에서 외래 키 무결성 예외가 발생한다. 예를 들어 User 엔티티와 Article 엔티티가 있다고 보자. User와 Article는 일대다의 관계를 가진다. User 하나에 여러 개의 Article가 있는 셈이다. 여기서 만약 User를 삭제한다면 삭제한 User에 연결된 Article에서는 에러가 발생하는 것이다. 다시 말해 연관관계가 끊어졌다고 할 수 있다. 이러한 상황에서  User와 연관관계가 끊어진 Article를 고아 객체라고 한다. 그렇기에 부모 엔티티를 삭제할 때는 연관된 자식 엔티티를 모두 삭제한 후에 부모 엔티티를 삭제해야 한다. 하지만 이는 코드도 증가하고 번거로운 과정일 것이다. 이럴 때 부모를 삭제하면 자동으로 자식들도 삭제된다면 얼마나 좋을까?!

그러기 위한 방식은 두가지 있다.

 

첫 번째 방식은 아래와 같다. 

 

@Entity
public class User{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany(mappedBy = "user", orphanRemoval = true)
    private List<Article> articles = new ArrayList<>();
}

 

위와 같이 orphanRemoval = true를 설정해주면 된다.

이렇게 하면 User를 삭제할 시 연관관계가 있는 Article들도 같이 삭제될 것이다. 

삭제 순서는 외래 키 제약 조건을 고려해서 자식을 먼저 삭제하고 부모를 삭제한다.

또한 부모 엔티티에서 자식엔티티에 대한 참조 즉, articles에서 특정 article를 없애기만 해도 해당되는 article이 삭제된다는 것이다. 

여기서 주의할 점은 특정 엔티티가 개인 소유하는 엔티티에만 이 기능을 적용해야 한다. 만약 삭제한 엔티티를 다른 곳에서도 참조한다면 문제가 발생할 수 있다. 이런 이유로 orphanRemoval은 @OneToOne, @OneToMany에만 사용할 수 있다.

 

두 번째 방식은 영속성 전이 특성을 이용하는 것이다. 아래는 예시 코드이다. 

 

@Entity
public class User{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
    private List<Article> articles = new ArrayList<>();
}

 

cascade = CascadeType.REMOVE를 추가하면서 User를 삭제할 시 Article도 같이 삭제할 수 있다. 

참고로 cascade를 단다는 것은 영속성 전이 특성을 부여한다는 것인데 영속성 전이란 특정 엔티티를 영속성 상태로 만들 때 연관된 엔티티도 함께 영속성 상태로 변경한다는 것을 의미한다. 그렇기에 단순이 삭제 기능뿐만이 아니라 다른 기능들도 있다. 

다른 기능들은 아래와 같다.

 

public enum CascadeType {
    All,     // 모두 적용
    PERSIST, // 영속
    REMOVE,  // TKRWP
    MERGE,   // 병합
    REFRESH, // REFRESH
    DETACH,  // DETACH
}

 

그렇다면 orphanRemoval = true 와 cascade = CascadeType.REMOVE의 차이는 무엇일까??

orphanRemoval = true 는 연관된 엔티티 간의 참조가 끊어질 때 삭제가 이루어진다. 

하지만 cascade = CascadeType.REMOVE 는 부모 엔티티를 삭제하면 자식 엔티티를 삭제하는 것이지 참조가 끊어질 때 삭제가 이루어지는 것은 아니다. 

 

출처:https://khdscor.tistory.com/18#:~:text=%EC%B2%AB%20%EB%B2%88%EC%A7%B8%20%EB%B0%A9%EC%8B%9D%EC%9D%80%20%EC%95%84%EB%9E%98%EC%99%80%20%EA%B0%99%EB%8B%A4.&text=%EC%9C%84%EC%99%80%20%EA%B0%99%EC%9D%B4%20orphanRemoval%20%3D%20true%EB%A5%BC,%ED%95%98%EA%B3%A0%20%EB%B6%80%EB%AA%A8%EB%A5%BC%20%EC%82%AD%EC%A0%9C%ED%95%9C%EB%8B%A4.

저작자표시 (새창열림)

'Stack > Spring' 카테고리의 다른 글

스프링부트 DB 작동 방식과 원리  (1) 2026.01.21
N+1 문제 해결로 쿼리 성능 개선하기  (0) 2022.08.11
(CI/CD) Codedeploy 배포 GitAction 에 GitIgnore 파일 적용하는법  (0) 2022.07.12
SQL 관계 데이터 베이스 삭제 시 참조키 관련 주의 사항  (0) 2022.07.12
Entity table 에 @setter 쓰지않기 + 대처방안  (0) 2022.07.12
'Stack/Spring' 카테고리의 다른 글
  • 스프링부트 DB 작동 방식과 원리
  • N+1 문제 해결로 쿼리 성능 개선하기
  • (CI/CD) Codedeploy 배포 GitAction 에 GitIgnore 파일 적용하는법
  • SQL 관계 데이터 베이스 삭제 시 참조키 관련 주의 사항
김코딩개발자
김코딩개발자
  • 김코딩개발자
    김코딩의 개발로그
    김코딩개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (69)
      • 개발이야기 (19)
        • 개발로그 (7)
        • 항해일지 (11)
      • Develop (0)
      • Life (0)
      • Stack (29)
        • C++ (6)
        • Ext.js (1)
        • Spring (18)
        • Java (2)
        • JavaScript (2)
      • TechTrend (0)
      • TechKnowledge (20)
        • CS관련지식 (9)
        • 알고리즘 (9)
        • 네트워크 (2)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    직장인
    지연수치표
    올바른 괄호
    개발 설계 문서
    자바스크립트입문
    데이터 용량단위
    서비스경험
    동시성제어
    프로그래머스
    프로그래머스 멀리뛰기
    개발일기
    응답지연값
    데이터 마이그레이션
    서비스 경험
    괄호 회전하기
    개발입문
    동적계획법
    DB원리
    osi 2계층
    ip통신
    네트워크
    lan 통신
    software docs
    프로그래머스 LV2
    관점지향프로그래밍
    개발 문서 작성방법
    시간복잡도
    괄호문제
    SpringBoot DB
    대규모 트래픽
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
김코딩개발자
JPA 특정 엔티티 삭제시 연관된 엔티티도 함께 삭제하기
상단으로

티스토리툴바