Post

(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.