반응형
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이 기능을 사용하면 된다. JPA는 CASCADE 옵션으로 영속성 전이를 제공한다.
// 부모 엔티티
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "parent")
private List<Child> children = new ArrayList<Child>();
...
}
//자식 엔티티
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
@ManyToOne
private Parent parent;
...
}
부모 엔티티가 여러가지 자식 엔티티를 가지고 있다.
// 부모 자식 저장
private static void saveNoCascade(EntityManager em) {
// 부모 저장
Parent parent = new Parent();
em.persist(parent);
// 1번 자식 저장
Child child1 = new Child();
child1.setParent(parent); // 자식 -> 부모 연관관계 설정
parent.getChildren().add(child1); // 부모 -> 자식
em.persist(child1);
// 2번 자식 저장
Child child2 = new Child();
child2.setParent(parent); // 자식 -> 부모 연관관계 설정
parent.getChildren().add(child2); // 부모 -> 자식
em.persist(child2);
}
JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다. 따라서 예제를 보면 부모 엔티티도 영속 상태로 만들고 자식 엔티티도 각각 영속 상태로 만든다. 이럴 때 영속성 전이를 사용하면 부모만 영속 상태로 만들면 연관된 자식까지 한 번에 영속 상태로 만들 수 있다.
영속성 전이: 저장
@Entity
public class Parent {
...
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> children = new ArrayList<Child>();
...
}
부모를 영속화할 때 연관된 자식들도 함께 영속화하라고 cascade = CascadeType.PERSIST 옵션을 설정했다.
private static void saveWithCascade(EntityManager em) {
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
child1.setParent(parent); //연관관계 추가
child2.setPatent(parent); //연관관계 추가
parent.getChildren().add(child1);
parent.getChildren().add(child2);
//부모 저장, 연관된 자식들 저장
em.persist(parent);
}
영속성 전이: 삭제
저장한 부모와 자식 엔티티를 모두 제거하려면 각각의 엔티티를 하나씩 제거해야 한다.
Parent findParent = em.find(Parent.class, 1L);
Child findChild1 = em.find(Children.class, 1L);
Child findChild2 = em.find(Children.class, 2L);
em.remove(findChild1);
em.remove(findChild2);
em.remove(findParent);
영속성 전이는 엔티티를 삭제할 때도 사용할 수 있다. CascadeType.REMOVE로 설정하고 다음 코드처럼 부모 엔티티만 삭제하면 연관된 자식 엔티티도 함께 삭제된다.
Parent findParent = em.find(Parent.class 1L);
em.remove(findParent);
만약 CascadeType.REMOVE를 설정하지 않고 위 코드를 실행하게 되면 부모 엔티티만 삭제된다. 하지만 데이터베이스의 부모 로우를 삭제하는 순간 자식 테이블에 걸려 있는 외래 키 제약조건으로 인해, 데이터베이스에서 외래키 무결성 예외가 발생한다.
CASCADE의 종류
public enum CascadeType {
ALL, // 모두 적용
PERSIST, // 영속
MERGE, // 병합
REMOVE, // 삭제
REFRESH, // REFRESH
DETACH // DETACH
}
다음처럼 여러 속성을 같이 사용할 수 있다.
cascade = {CascadeType.PERSIST, CascadeType.REMOVE}
위 코드는 em.persist(), em.remove()를 실행할 때 바로 전이가 발생하지 않고 플러시를 호출할 때 전이가 발생한다.
반응형
'JPA' 카테고리의 다른 글
객체지향 쿼리 언어 소개 (0) | 2023.09.22 |
---|---|
값 타입 (0) | 2023.09.22 |
즉시 로딩과 지연 로딩 (0) | 2023.07.31 |
프록시 (0) | 2023.07.28 |
@SecondaryTable : 엔티티 하나에 여러 테이블 매핑 (0) | 2023.06.13 |