이 글은 김영한님의 JPA 강의 중 8장 프록시와 연관관계 관리를 듣고 정리한 내용입니다 :)
강의 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
교재 : 자바 ORM 표준 JPA 프로그래밍🤷♀️
: 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 같이 영속 상태로 만들고 싶을 때 사용한다. (지연/즉시로딩과 아무 관련이 없음)
예를 들면 부모 엔티티 저장 시, 자식 엔티티도 함께 저장하려는 경우 (단, 부모가 하나일 때)
사용 예시 : @OneToMany(mappedBy="parent", cascade = CascadeType.ALL)
@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); // 부모를 통해서 하나의 자식만 제거할 때
@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<>();
}