Home 영속성 전이(CASCADE), 고아 객체
Post
Cancel

영속성 전이(CASCADE), 고아 객체

영속성 전이(CASCADE)

  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶은 경우 사용한다.
    • ex) 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장하고 싶다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity
public class Parent {
	
	@Id @GeneratedValue
	private Long id;

	private String name;

	@OneToMany(mappedBy = "parent")
	private List<Child> childList = new ArrayList<>();

	public void addChild(Child child) {
		childList.add(child);
		child.setParent(this);
	}

	//...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
public class Child {

	@Id @GeneratedValue
	private Long id;

	private String name;

	@ManyToOne
	@JoinColumn(name = "parent_id")
	private Parent parent;

	//...
}

위와 같이 엔티티 코드를 작성했을 때

1
2
3
4
5
6
7
8
9
10
11
Child child1 = new Child();
Child child2 = new Child();

Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);

em.persist(parent);

em.persist(child1);
em.persist(child2);

단순히 parent만 persist() 해주는 것이 아닌 child도 하나하나 persist() 해주어야 의도한 대로 DB에 반영된다.

객체 입장에서는 parent 위주로 코드를 작성했는데 child도 신경써주어야 되는 것이다.

1
2
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();

이럴 때 영속성 전이(cascade)를 사용하면 parent만 persist() 해주어도 의도한 대로 child까지 persist() 되는 것을 볼 수 있다.

  • 영속성 전이는 연관관계를 매핑하는 것과 아무런 관계가 없다.
  • 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐이다.

주의

  • 부모와 자식간의 라이프 싸이클(등록 및 삭제 등)이 유사할 때 사용한다.
  • 그리고 parent같이 child를 소유하는 객체가 단 하나일때만 사용한다.
    • ex) 게시글과 첨부 파일의 관계
    • 만약 child가 위와 같이 parent와도 관련이 되어 있고, Member와도 관련이 되어 있으면 사용하면 안된다.

CASCADE의 종류

  • ALL: 모두 적용
  • PERSIST: 영속
  • REMOVE: 삭제
  • MERGE: 병합
  • REFRESH: REFRESH
  • DETACH: DETACH

고아 객체

  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티

부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제할 경우 사용한다.

1
2
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
  • orphanRemoval = true
  • Parent parent1 = em.find(Parent.class, id); parent1.getChildren().remove(0);
    • DELETE FROM CHILD WHERE ID = ?

주의

  • 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능이다.
  • 참조하는 곳이 하나일때만 사용한다.
    • 특정 엔티티가 개인 소유할 때 사용한다.
  • @OneToOne, @OneToMany만 가능하다.

참고: 개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화하면 부모를 제거할 때 자식도 함께 제거된다.

이는 CascadeType.REMOVE 처럼 동작한다.

영속성 전이 + 고아 객체, 생명 주기

  • CascadeType.ALL + orphanRemoval = true
    • 이 두 옵션을 모두 활성화하면 부모 엔티티를 통해 자식의 생명 주기를 관리할 수 있다.
    • Parent만 persist 혹은 remove를 하면 자식도 동일한 생명 주기를 가진다.
  • 도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용하다.

가장 중요한 것은 영속성 전이나 고아 객체 전부 특정 엔티티가 개인 소유할 때 사용해야 한다는 것이다.

This post is licensed under CC BY 4.0 by the author.