@Setter
@Getter
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> childes = new ArrayList<>();
public void addchild(Child child) {
childes.add(child);
child.setParent(this);
}
}
@Setter
@Getter
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Parent parent;
}
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addchild(child1);
parent.addchild(child2);
em.persist(parent);
em.persist(child1);
em.persist(child2);
현재 Parent와 Child는 1:N 양방향 연관관계로 맺어진 상황이다. 여기서 3가지 인스턴스를 모두 영속화 시키기 위해서는 em.persist
를 3번 호출해서 영속화해야한다.
JPA에서는 이를 간편하게 처리할 수 있는 방법으로 영속성 전이(CASCADE)의 PERSIST 옵션을 제공한다.
영속성 전이
@OneToMany(mappedBy = "parent",cascade = CascadeType.PERSIST)
private List<Child> childes = new ArrayList<>();
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addchild(child1);
parent.addchild(child2);
em.persist(parent);
예제
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this);// 외래 키(연관 관계) 설정
}
}
@Test
@Transactional
@Rollback(value = false)
@DisplayName("영속성 전이 삭제")
void test4() {
// 고객 Robbie 를 조회합니다.
User user = userRepository.findByName("Robbie");
System.out.println("user.getName() = " + user.getName());
// Robbie 가 주문한 음식 조회
for (Food food : user.getFoodList()) {
System.out.println("food.getName() = " + food.getName());
}
// Robbie 탈퇴
userRepository.delete(user);
}
고객 Entity의 @OneToMany 애너테이션에 연관된 음식 Entity도 자동으로 삭제될 수 있도록 REMOVE 옵션을 추가한다.
Robbie 고객 Entity 객체를 조회한 후 해당 객체를 delete 하자 자동으로 연관된 음식 데이터들이 삭제된다.
CascadeType.ALL
: 모든 Cascade 옵션을 적용한다.CascadeType.PERSIST
: 엔티티를 영속화할 때, 연관된 엔티티도 함께 영속화한다.CascadeType.REMOVE
: 엔티티를 제거할 때, 연관된 엔티티도 함께 제거한다.CascadeType.MERGE
: 엔티티 상태를 병합할 때, 연관된 엔티티도 함께 병합한다.CascadeType.REFRESH
: 부모 엔티티를 Refresh하면, 연관된 엔티티도 함께 Refresh된다.CascadeType.DETACH
: 부모 엔티티를 Detach하면, 연관된 엔티티도 함께 Detach된다.@OneToMany
가 걸린 엔티티에 Cascade를 걸어주면된다.orphanRemoval=true
옵션을 @ OnetoMany
에 걸어주면 되는 것이다.@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this);// 외래 키(연관 관계) 설정
}
}
처음 둘의 개념을 접했을때 차이를 구분할 수 없었다.
https://hongchangsub.com/jpa-cascade-2/
https://velog.io/@chiyongs/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%A0%84%EC%9D%B4-CASCADE