JPA - CascadeType.REMOVE vs orphanRemoval

송형근·2024년 8월 30일
0

TIL

목록 보기
26/43
post-thumbnail

프로젝트를 진행하던 중 @OneToMany 관계로 되어있는 엔티티가 List를 clear를 해도 자식 Entity가 삭제되지 않는 현상이 발생했음

  • 원하던 동작
    • List.clear() 시 자식 엔티티들이 모두 삭제

고아 객체

  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 지칭

CascadeType.Remove

  • 부모 엔티티가 삭제되면 자식 엔티티도 삭제함
  • 부모 엔티티와 자식 엔티티의 연관관계를 제거해도, 자식 엔티티는 삭제되지 않고 그대로 DB에 남아있음

orphanRemoval = true

  • 부모 엔티티가 삭제되면 자식 엔티티도 삭제됨
  • 부모 엔티티와 자식 엔티티의 연관관계를 제거하면, 자식 엔티티는 고아 객체가 되어 DB에서 삭제되는 옵션

프로젝트 적용

  • Order Entity
    @Getter
    @Setter
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Entity(name = "p_orders")
    public class Order extends BaseEntity {
        @Id
        @Column(name = "order_id")
        private UUID orderId;
    
        @Column(name = "user_name", nullable = false , length = 100)
        private String userName;
    
        @ManyToOne
        @JoinColumn(name = "store_id")
        private Store store;
    
        @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
        private List<OrderProduct> orderProducts;
    
    //    @ManyToOne
    //    @JoinColumn(name = "dest_id")
        @Column(name = "dest_id", nullable = false)
        private UUID destId;
    
        @Column(name = "order_type")
        private OrderType orderType;
    
    //    @Column(name = "is_reviewed")
    //    private boolean isReviewed;
    
        public void addOrderProduct(OrderProduct orderProduct) {
            this.orderProducts.add(orderProduct);
        }
    
        public void updateOrderProducts(List<OrderProduct> updatedOrderProducts) {
            this.orderProducts.clear();
            for(OrderProduct orderProduct : updatedOrderProducts) {
                addOrderProduct(orderProduct);
            }
        }
    
        public void deleteOrderProduct(String userName) {
            for(OrderProduct orderProduct : this.orderProducts) {
                orderProduct.setDeleted(LocalDateTime.now(), userName);
            }
        }
    }
  • OrderProduct Entity
    @Getter
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    @Entity(name = "p_order_products")
    public class OrderProduct extends BaseEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.UUID)
        @Column(name = "order_product_id")
        private UUID orderProductId;
    
        @ManyToOne
        @JoinColumn(name = "order_id")
        private Order order;
    
        @ManyToOne
        @JoinColumn(name = "product_id")
        private Product product;
    
        @Column(name = "product_quantity")
        private Long productQuantity;
    }
  • 기존에는 updateOrderProducts 메서드 실행 시 OrderProduct가 삭제되지 않았었지만, orphanRemoval=true 옵션 추가 후 삭제 됨
profile
기록을 남겨보자

0개의 댓글