[JPA/김영한] 영속성 전이, 고아객체란

수영·2021년 10월 11일
1

JPA 공부!

목록 보기
8/9

이 글은 김영한님의 JPA 강의 중 8장 프록시와 연관관계 관리를 듣고 정리한 내용입니다 :)
강의 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
교재 : 자바 ORM 표준 JPA 프로그래밍🤷‍♀️


영속성 전이(Cascade)란

: 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 같이 영속 상태로 만들고 싶을 때 사용한다. (지연/즉시로딩과 아무 관련이 없음)

단, 두 가지 조건이 만족할 때만 사용한다.

  1. Lifecycle이 같을 때 (생성-소멸이 같이 되는 경우)
  2. 단일 소유자일때 (연관 관계가 하나일때)

예를 들면 부모 엔티티 저장 시, 자식 엔티티도 함께 저장하려는 경우 (단, 부모가 하나일 때)

Cascade 종류

사용 예시 : @OneToMany(mappedBy="parent", cascade = CascadeType.ALL)

  • ALL : 모두 적용
  • PERSIST : 영속
  • REMOVE : 삭제
  • MERGE : 병합
  • REFRESH : REFRESH
  • DETACH : DETACH
@Entity
public class Parent {
    @Id @GeneratedValue
    private Long id;
 
    @OneToMany(mappedBy="parent", cascade = CascadeType.ALL)
    private List<Child> childList = new ArrayList<Child>();

		// 연관관계 편의 메소드 - 양방향 연관관계 매핑해주기
		public void addChild(Child child) {
				childList.add(child); // '일'쪽에서 '다' 매핑
				child.setParent(this); // '다'쪽에서 '일' 매핑
}
 
@Entity
public class Child {
    @Id @GeneratedValue
    private Long id;
 
    @ManyToOne
		@JoinColumn (name = "")
    private Parent parent;
}

// ----------------try-catch에서의 테스트 코드-----------------
Parent parent = new Parent();
 
Child child1 = new Child();
Child child2 = new Child();
parent.addChild(child1); // parent쪽에서의 연관관계 편의 메소드 참고
parent.addChild(child2);

em.persist(parent);
// cascade를 걸어줄 경우, 아래 코드가 자동으로 생성
// em.persist(child1);
// em.persist(child2);

고아 객체 삭제란

: 부모 엔티티와 연관관계가 끊어진, 혹은 부모가 사라진 자식 엔티티를 자동으로 삭제하는 기능

단, 참조한 곳이 한 곳일 때만 사용! 예를 들면 쇼핑몰에서 상품 A가 삭제되면 A의 상세페이지에서 해당 후기들을 모두 삭제하는 기능!

@Entity
public class Parent {
    @Id @GeneratedValue
    @Column(name = "PARENT_ID")
    private Long id;

    @OneToMany(mappedBy = "parent", orphanRemoval = true)
    private List<Child> children = new ArrayList<Child>();
}

// ----------------try-catch에서의 테스트 코드-----------------
Parent parent1 = em.find(Parent.class, id);
parent1.getChildren().remove(0); // 자식 엔티티를 부모 컬렉션에서 제거 -> 고아객체 자동 삭제

영속성 전이 + 고아 객체 함께 사용하면,

: 부모 엔티티로 자식 엔티티의 생명주기를 관리할 수 있다.

: @OneToMany(mappedBy="parent", cascade = CascadeType.ALL, orphanRemoval = true)

이 방식은 도메인 주도 설계(DDD)의 Aggregate Root 에서 유용함 → 후에 추가 공부

@Entity
public class Parent {
		...
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Child> children = new ArrayList<Child>();
}

// ----------------try-catch에서의 테스트 코드-----------------
Parent parent = new Parent();
Child child1 = new Child();
parent.addChild(child); // 연관관계 매핑

// 부모만 등록,제거하면 자식은 자동으로 등록,제거된다!
em.persist(parent);
em.remove(parent); // 전체 자식들 제거
parent.getChildList().remove(index:0); // 부모를 통해서 하나의 자식만 제거할 때

8장 예제

  • 모두 지연로딩으로 변경 : @ManyToOne, @OneToOne
  • 영속성 전이 ALL로 설정 :
    Order → Delivery 주문할 때 바로 배송 정보도 저장 (생명 주기 맞추기)
    Order → OrderItem
@Entity
public class Order {
    @Id @GeneratedValue
    @Column(name = "ORDER_ID")
    private Long id;

		@OneToOne(fetch = LAZY, cascade = ALL)
		@JoinColumn(name = "DELIVERY_ID")
    private Delivery delivery;

    @OneToMany(mappedBy = "order", cascade = ALL)
    private List<OrderItem> orderItems = new ArrayList<>();
}
profile
🎵🎵🎵🎶🎵

0개의 댓글