JPA
[JPA] 16. 영속성 전이(CASCADE)
inuma
2021. 1. 18. 23:16
프로젝트 git url | github.com/rtef23/JpaStudy |
필요 | 1. docker 2. docker-compose |
프로젝트 정보 | mysql : 5.7 - docker image java : 1.8 |
영속성 전이(CASCADE)
- 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만드는 것
- 부모 엔티티를 저장할 때, 자식 엔티티도 함께 저장하는 것
@Entity
public class Parent {
@Id @GeneratedValue private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children = new ArrayList<>();
...
}
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "children")
private Parent parent;
...
}
Child child1 = new Child();
child1.setName("child-1");
Child child2 = new Child();
child2.setName("child-2");
Parent parent = new Parent();
parent.setName("parent-1");
parent.addChild(child1);
parent.addChild(child2);
entityManager.persist(parent);
- parent만 저장(persist)하는데 연관된 child들도 같이 저장되게 된다.
- 연관된 엔티티가 다른 엔티티와 연관관계가 있는 경우, CASCADE를 쓰는 것은 운영을 복잡하게 만들 수 있다.(종속적인 경우에만 사용하는 것을 추천)
CASCADE 종류
- ALL
- ; 모두 적용
- PERSIST
- ; 영속
- REMOVE
- ; 삭제
- MERGE
- ; 병합
- REFRESH
- DETACH
고아 객체
- 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
- orphanRemoval = true
@Entity
public class Parent {
@Id @GeneratedValue private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> children = new ArrayList<>();
...
}
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "children")
private Parent parent;
...
}
- 별도의 remove api를 사용하지 않았지만 Parent - Children 컬렉션 0번에 있던 엔티티를 제거하는 쿼리가 실행되었다.(부모 엔티티와 연관 관계가 끊어졌기 때문에)
Parent findParent1 = entityManager.find(Parent.class, parent.getId());
findParent1.getChildren().remove(0);
- 부모 객체가 지워지는 경우에도 하위 자식을 제거하는 쿼리가 전송되게 된다.
- 부모 id로 Child delete 쿼리를 실행하면 1번만 수행하게 될 듯 하지만 개별 Child의 id로 삭제 쿼리가 전송되게 된다.
- CascadeType.REMOVE와 같이 동작하게 된다.
Parent findParent1 = entityManager.find(Parent.class, parent.getId());
entityManager.remove(findParent1);
주의할 점
- 특정 엔티티가 개인 소유할 때 사용
- @OneToOne, @OneToMany에서만 사용 가능
영속성 전이 + 고아 객체, 생명 주기
- 두 옵션을 모두 활성화하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있음
- DDD에서 Aggregate root 개념을 구현할 때 유용