JPA | 영속성 전이 : CASCADE / 고아 객체

바다·2024년 5월 24일
0

DataBase

목록 보기
2/6
post-thumbnail

영속성 전이 : CASCADE

특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때

예) 부모 엔티티를 저장할 때, 자식 엔티티도 함께 저장


저장

CascadeType.PERSIST

음식 테이블과 주문 테이블이 있고,
음식은 여러 주문에 저장될 수 있다 👉 1 : N

엔티티 매핑

@Entity
public class Food {
	...
    
    @OneToMany(mappedBy = "food", cascade = CascadeType.PERSIST)
    private List<Order> orderList = new ArrayLIst<>();
    
    ...
}

@Entity
public class Order {
	...
    
    @ManyToOne
    @JoinColum(name = "food_id")
    privat Food food;
    
    ...
}

부모 엔티티 저장

food(부모) 엔티티 만 영속화 해도 CascadeType.PERSIST로 인해 설정한 order(자식) 엔티티까지 함께 영속화해서 저장!

//부모 엔티티 저장 시 자식 엔티티도 저장
private static void save(EntityManager em) {
	Order order1 = new Order();
	Order order2 = new Order();
    
    Food food = new Food();
    
    order1.setFood(food);
    order2.setFood(food);
    
    food.getOrderList().add(order1);
    food.getOrderList().add(order2);
    
    em.persist(food);	//order도 영속성 전이로 저장
}

삭제

CascadeType.REMOVE

엔티티 매핑

@Entity
public class Food {
	...
    
    @OneToMany(mappedBy = "food", cascade = CascadeType.REMOVE)
    private List<Order> orderList = new ArrayLIst<>();
    
    ...
}

@Entity
public class Order {
	...
    
    @ManyToOne
    @JoinColum(name = "food_id")
    privat Food food;
    
    ...
}

부모 엔티티 삭제

CascadeType.REMOVE로 인해, food(부모) 엔티티를 삭제하면 연관된 order(자식) 엔티티도 함께 삭제된다

//부모 엔티티 삭제 시 자식 엔티티도 삭제
private static void remove(EntityManager em) {
	Food food = em.find(Food.class, 1L);
    em.remove(food);
}

연관관계 제거

하지만 food(부모) 엔티티와 order(자식) 엔티티의 연관관계를 제거했을 때, order(자식) 엔티티는 삭제되지 않고 그대로 DB에 남아있다

// 부모 엔티티에서 자식 엔티티와의 연관관계 끊기
private static void remove_persistence(EntityManager em) {
	Food food = em.find(Food.class, 1L);
    food.getOrders().get(0).setFood(null);
    
    em.flush();
}

이런 상황에서, order(자식) 엔티티는 이제 참조할 food(부모)가 없는, 고아 객체 가 된다


고아 객체 관리

orphanRemoval = true

CascadeType.REMOVE는 부모 엔티티와 자식 엔티티의 연관관계 제거 시, 자식 엔티티는 고아 객체가 되지만

orphanRemoval = true 옵션을 사용하면 부모 엔티티와 연관관계가 제거된 고아 객체도 함께 DB에서 삭제가 된다

엔티티 매핑

@Entity
public class Food {
	...
    
    @OneToMany(mappedBy = "food", orphanRemoval = true)
    private List<Order> orderList = new ArrayLIst<>();
    
    ...
}

@Entity
public class Order {
	...
    
    @ManyToOne
    @JoinColum(name = "food_id")
    privat Food food;
    
    ...
}

부모 엔티티 삭제

CascadeType.REMOVE 와 같이 부모 엔티티가 삭제되면, 자식 엔티티 도 함께 삭제 된다

//부모 엔티티 삭제시 자식 엔티티도 삭제
private static void orphanRemoval_remove(EntityManager) {
	Food food = em.find(Food.class, 1L);
    em.remove(food);
    
    em.flush();
}

연관관계 제거

그리고, 부모 엔티티와 자식 엔티티 사이의 연관관계가 제거 되면, 고아가 된 자식 객체는 삭제된다

// 연관관계 제거시 고아 객체 삭제
private static void orphanRemoval_Persistence(EntityManager) {
	Food food = em.find(Food.class, 1L);
    food.getOrderList().get(0).setFood(null);
    
    em.flush();
}

주의 사항

  • CascadeType.REMOVE, orphanRemoval = true 모두 자식 엔티티에 단 하나의 부모 엔티티가 연관되어 있는 경우에만 사용해야 한다
  • 자식 엔티티와 서로 다른 2개 이상의 부모 엔티티가 연관관계를 갖고 있다면, 사용을 조심해야 한다.
    자식 엔티티를 삭제할 상황이 아님에도, 연관된 1개의 부모 엔티티가 삭제 또는 해당 연관관계를 제거함으로써 자식 엔티티가 삭제될 수 있기 때문
profile
ᴘʜɪʟɪᴘᴘɪᴀɴs 3:14

0개의 댓글