(JPA)영속성 전이와 고아객체
영속성 전이와 고아객체
영속성 전이(CASCADE)
- 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을때 사용한다.
엔티티 생성
- 일대다, 다대일 양방향 관계를 가지는 엔티티를 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@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
@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
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);
- CASCADE가 없을때 엔티티와 연관된 엔티티 모두를 저장하기 위해서는 persist를 3번 호출해야 한다.(매우 불편)
1
2
@OneToMany(mappedBy = "parent", cascaed = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
- CASCADE 설정을 해주면 한번의
em.persist(parent)
로 child 까지 함께 저장이 가능해진다.
영속성 전이 주의
- 영속성 전이는 연관관계 매핑과는 아무련 관련이 없다.
- 엔티티를 영속화 할 때 연관된 엔티티도 함께 영속화 하는 편리함을 제공할 뿐이다.
- 하나의 부모가 자식을 관리할때(소유자가 하나일때) 사용하면 매우 의미가 있다.
- 라이프 사이클이 유사한 엔티티간에 사용하면 좋다.
- 만약 다른 엔티티에서 자식을 관리하거나, 연관관계가 있으면 사용하면 안된다.
영속성 전이 종류
- ALL: 모두 적용
- PERSIST: 영속
- REMOVE: 삭제
- MERGE: 병합
- REFERESH: REFERESH
- DETACH: DETACH
고아 객체
고아 객체 사용법
참조가 제거된 엔티티는 다론 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
고아 객체 제거: 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능
orphanRemoval = true
를 설정
1
2
3
4
5
@OneToMany(mappedBy = "parent", cascaed = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
Parent parent = em.find(Parent.class, parent.getId());
parent.getChildList().remove(0); // 자식 엔티티를 컬렉션에서 제거
- 위에 코드처럼 자식 엔티티를 컬렉션에서 제거하게 되면, 자동으로 child를 삭제 하는 쿼리가 발생하게 된다.
- DELETE FROM CHILD WHERE ID = ?
고아 객체 주의
- 참조하는 곳이 하나일 때 사용해야 한다.
- 특정 엔티티의 소유자가 하나일때 사용
- @OneToOne, @OneToMany만
영속성 전이 + 고아 객체
CascadeType.ALL + orphanRemoval = true
스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명주기를 관리 할 수 있다.
도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용하다.
REFERENCE
#JPA_즉시로딩 #JPA_지연로딩
This post is licensed under CC BY 4.0 by the author.