(Cascade 영속성 전이)
RDB에서의 cascade 기능을 JPA에서도 사용할 수 있다.
Member와 Team은 N:1 관계이다. Team은 여러 Member를 가질 수 있는데, member 객체가 하나 생성될 때마다 일일히 em.persist(member) 해주기 귀찮을 수 있다.
굳이 귀찮음의 문제가 아니더라도 member 중심이 아닌 team 중심적 프로그래밍을 하고 싶을 수도 있다.
이때 cascade 속성을 사용해서 멤버들을 포함한 team 하나만 persist() 함으로써 모든 멤버들을 한 번에 persist() 할 수 있다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
.
.
.
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
@OneToMany(mappedBy = "team", cascade = CascadeType.ALL)
private List<Member> members = new ArrayList<>();
}
이렇게 하면 연관관계의 주인인 team이 persist 될 때 cascade 하게 그 안의 모든 member들도 함께 처리된다.
보통 CascadeType.ALL, CascadeType.PERSIST 둘 중 하나를 선택하여 사용한다.
(완전히 같이 가도록 두든지 아님 삭제를 막기 위해 저장에 대해서만 허용하든지)
주의할 점은, Member처럼 Team이라는 단일 엔티티에만 종속된 경우에는 cascade로 함께 관리해도 무방하지만 만약 Member를 참조하는 다른 엔티티가 또 존재한다면 이 경우엔 cascade를 쓰지 않고 따로 관리하는 것이 좋다.
(이 경우에도 cascade를 쓰면 운영이 너무 어려워진다.
예를 들어, Member를 가지는 다른 엔티티가 존재하는데 Team에서 Member에 CascadeType.ALL을 해놓으면?
Team이 지워질 때 Member도 함께 지워지고, 그 Member를 참조하던 다른 엔티티에 문제가 생길 수 있다)
(고아 객체)
부모와 참조관계를 형성한 자식 객체가 존재한다.
이 부모가 사라진다면 자식은 고아가 된다. 고아가 된 객체를 자동적으로 처리하는 CascadeType.REMOVE 와 같은 동작을 수행하도록 하는 옵션이 있다.
@OneToMany(mappedBy = "관계의 주인", orphanRemoval = true)
orphanRemoval도 Cascade와 같은 이유로 인해 단일 참조 관계일 경우에만 사용해야 한다.
cascade = CascadeType.ALL + orphanRemoval = true -> 자식의 생명주기를 부모가 관리???
'김영한님 스프링 강의 정리 > JPA' 카테고리의 다른 글
임베디드 타입 (복합 값 타입) (0) | 2021.03.02 |
---|---|
JPA의 데이터 타입 (엔티티 타입, 값 타입) (0) | 2021.03.02 |
즉시 로딩과 지연 로딩 (0) | 2021.03.01 |
상속 관계 매핑 전략 (JOINED, SINGLE_TABLE, TABLE_PER_CLASS) (0) | 2021.02.25 |
@ManyToMany를 사용하면 안 되는 이유 (0) | 2021.02.24 |