[TIL] 영속성 전이(CASCADE)와 고아객체

wannabeing·2025년 5월 1일
1

SPARTA-TIL

목록 보기
19/22
post-thumbnail

영속성 전이(Cascade)의 개념과 사용 시점

  • 영속성 전이는 연관관계와 전혀 관련이 없다.
  • 객체를 영속상태로 만들 때, 연관된 객체도 함께 영속상태로 만드는 편리함만 제공한다.
  • 보통 N:1의 관계에서 1인 객체만이 N을 관리할 때 사용한다.
    → 부모가 하나일 때...? 😅 단일 소유자(부모)만 존재할 때
  • 부모/자식의 라이프사이클이 유사할 때 사용한다.
    부모삭제 = 자식삭제 , 부모저장 = 자식저장

CASCADE의 종류

  • ALL: 모두 적용
  • PERSIST: 부모가 영속상태 될 때, 자식도 함께 persist()
  • REMOVE: 삭제될 때 같이 삭제됨
  • MERGE: 부모를 병합할 때, 자식도 함께 병합됨
  • REFRESH: 부모를 새로고침할 때, 자식도 함께 DB 상태로 갱신됨
  • DETACH: 부모가 영속상태에서 제거될 때, 자식도 함께 detach()

부모객체가 영속상태가 될 때, 자식객체도 영속상태로 만들어보자.

Child childA = new Child();
Child childB = new Child();

Parent parent = new Parent();
parent.addChild(childA); // 자식을 부모리스트에 추가 및 자식객체에 부모 설정
parent.addChild(childB); // 자식을 부모리스트에 추가 및 자식객체에 부모 설정

entityManager.persist(parent); // 영속상태 및 Insert 쿼리 
entityManager.persist(childA); // 영속상태 및 Insert 쿼리
entityManager.persist(childB); // 영속상태 및 Insert 쿼리
  • Parent(1) : Child(N) 양방향 매핑이다.
  • FK는 Child에 존재한다.
  • 연관관계 설정 메서드(addChild)는 부모객체(N)에 존재한다.

현재 코드의 문제점

  • 부모가 자식관리를 했으면 좋겠다.
  • persist() 를 3번 호출해야된다...

✅ 코드 개선

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Parent {
	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	private String name;

	// ✅ Cascade Persist 설정
	@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
	private List<Child> children = new ArrayList<>();

	// 연관관계 데이터 설정 메서드
	void addChild(Child child){
		this.children.add(child); // 자식객체를 부모 자식리스트에 추가
		child.setParent(this); // 자식객체의 부모객체(this)를 설정
	}
}
Child childA = new Child();
Child childB = new Child();

Parent parent = new Parent();
parent.addChild(childA); // 부모의 자식리스트에 추가 및 자식객체에 부모 설정
parent.addChild(childB); // 부모의 자식리스트에 추가 및 자식객체에 부모 설정

entityManager.persist(parent); // ✅ 부모만 영속상태 및 Insert 쿼리
  • Parent객체 안에 있는 children 변수에 CascadeType.PERSIST설정을 하였다.
    Parent객체가 영속상태가 되면 해당 객체(Child)도 영속상태가 된다.라는 뜻이다!
    → 말그대로 영속성이 전이된다!!

고아객체

  • JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공한다.
    이 기능을 고아(ORPHAN) 객체 제거라고 한다.
  • 이 기능을 사용하면 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티가 자동으로 삭제된다.
  • CascadeType.REMOVE처럼 동작한다!
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> children = new ArrayList<>();

💡 영속성 전이(ALL)과 고아객체 제거를 같이쓴다면?

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> children = new ArrayList<>();
  • 부모 엔티티를 통해서 자식엔티티의 생명주기를 관리한다.
    DDD의 Aggregate Root 개념을 구현할 때 용이하다.

김영한 자바 ORM 표준 JPA 프로그래밍

profile
wannabe---ing

2개의 댓글

comment-user-thumbnail
2025년 5월 2일

들어도 들어도 헷갈리는 remove와 고아객체의 차이.. ㅠㅠ

1개의 답글