JPA에서 엔티티 간의 관계를 설정할 때, CascadeType.REMOVE와 orphanRemoval=true 옵션은 부모 엔티티와 자식 엔티티 간의 삭제 동작을 제어하는 중요한 기능이다. 이 두 옵션은 비슷한 역할을 하지만, 그 동작 방식과 적용되는 상황에서 차이가 있다. 아래에서 각각의 옵션에 대해 상세히 설명하고, 그 차이점을 명확히 하겠다.
CascadeType.REMOVE
CascadeType.REMOVE는 부모 엔티티가 삭제될 때, 연관된 자식 엔티티도 함께 삭제되도록 하는 옵션이다. 이 옵션은 부모 엔티티의 생명 주기와 자식 엔티티의 생명 주기를 일치시키는 데 사용된다.
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "parent")
private List<Child> children = new ArrayList<>();
}
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
부모 엔티티가 삭제될 때, CascadeType.REMOVE가 설정된 자식 엔티티도 함께 삭제된다. 부모 엔티티가 삭제되지 않는 한, 자식 엔티티는 독립적으로 삭제되지 않는다. 다만, 연관된 자식 엔터티를 삭제하기 전에 조회를 통해 영속성 콘텍스트에 먼저 로드된다. 자식 엔터티가 영속성 콘텍스트에 없다면 CascadeType.REMOVE는 적용되지 않는다.
자식 엔터티별로 DELETE 쿼리가 발생하므로 삭제할 엔터티가 많은 경우 성능 저하가 커지게 된다.
orphanRemoval=true
orphanRemoval=true는 부모 엔티티와의 관계가 끊어진 자식 엔티티(고아 객체)를 자동으로 삭제하는 옵션이다. 이 옵션은 부모 엔티티의 컬렉션에서 자식 엔티티가 제거될 때, 해당 자식 엔티티를 데이터베이스에서도 삭제하도록 한다.
orphanRemoval=false가 지정돼 있으면 DELETE가 아닌 UPDATE가 호출된다. orphanRemoval은 참조 없이 존재하지 않아야 할 엔터티를 정리하는 데 유용하다.
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> children = new ArrayList<>();
}
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
부모 엔티티의 컬렉션에서 자식 엔티티가 제거되면, 해당 자식 엔티티는 데이터베이스에서도 삭제된다.
부모 엔티티가 삭제될 때, orphanRemoval=true가 설정된 자식 엔티티도 함께 삭제된다.
자식 엔티티가 부모 엔티티와의 관계에서 제거되면, 자식 엔티티는 독립적으로 삭제된다.
차이점 요약
(1) 삭제 조건
CascadeType.REMOVE - 부모 엔티티가 삭제될 때만 자식 엔티티가 삭제된다.
orphanRemoval=true - 부모 엔티티가 삭제되거나, 부모 엔티티의 컬렉션에서 자식 엔티티가 제거될 때 자식 엔티티가 삭제된다.
(2) 적용 상황
CascadeType.REMOVE - 부모 엔티티의 생명 주기와 자식 엔티티의 생명 주기를 일치시키고자 할 때 사용된다.
orphanRemoval=true - 부모 엔티티와의 관계가 끊어진 자식 엔티티를 자동으로 삭제하고자 할 때 사용된다.
(3) 독립적인 삭제
CascadeType.REMOVE - 자식 엔티티는 부모 엔티티가 삭제될 때만 삭제된다.
orphanRemoval=true - 자식 엔티티는 부모 엔티티의 컬렉션에서 제거될 때도 삭제된다.
결론
CascadeType.REMOVE와 orphanRemoval=true는 JPA에서 부모-자식 관계의 엔티티 삭제를 제어하는 중요한 옵션이다. CascadeType.REMOVE는 부모 엔티티가 삭제될 때 자식 엔티티를 함께 삭제하는 데 사용되며, orphanRemoval=true는 부모 엔티티와의 관계가 끊어진 자식 엔티티를 자동으로 삭제하는 데 사용된다. 이 두 옵션을 적절히 활용하면, 엔티티 간의 관계를 보다 명확하고 일관성 있게 관리할 수 있다.
'Spring > JPA' 카테고리의 다른 글
양방향 @OneToOne 문제점과 해결 방법 (1) | 2024.10.30 |
---|---|
@ManyToOne 연관관계에서 부모 엔터티를 등록할 때 프록시 호출을 통해 JPA 최적화 하기 (0) | 2024.10.22 |
JPA 효과적인 양방향 연관관계 구성방법 (0) | 2024.10.16 |
JPA Buddy 플러그인을 이용해서 엔티티에 equals와 hashcode를 명시적으로 구현해야 하는 이유 (0) | 2024.06.22 |
[Querydsl] @OneToMany에서 조건 절과 Fetch Join을 함께 사용할 때 서브쿼리 사용하기 (0) | 2024.05.12 |
댓글