(Spring) 삭제 관련 Cascade 사용 여부에 따른 정리

2024. 10. 24. 17:30·Spring

1. Cascade 없이 직접 삭제하는 방식 (서비스 계층에서 처리)

구현 원리

  • 양방향 매핑 없이 @ManyToOne 단방향 연관관계만 사용.
  • 게시물(Board) 삭제 전에 댓글(Comment)과 좋아요(Like)를 서비스 계층에서 명시적으로 삭제.

엔터티 설정

@Entity
public class Board {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;
    private String content;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

@Entity
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "board_id")
    private Board board;

    private String content;
}

@Entity
public class Like {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "board_id")
    private Board board;
}

장점

  • 단순한 단방향 연관관계(@ManyToOne만 사용)로 설계가 간단함.
  • N+1 문제를 피할 수 있음: 불필요한 데이터 로딩이 없음.
  • 연관된 엔터티를 서비스 계층에서 명시적으로 삭제하여, 제어가 용이함.

단점 

  • 데이터 삭제 로직을 서비스 계층에서 처리해야 하므로 코드가 복잡해질 수 있음.
  • 댓글이나 좋아요가 많을 경우, 대량 삭제에 대한 성능 문제를 고려해야 함(필요 시 배치 처리 도입).

2. Cascade를 사용하는 방식 (양방향 매핑 활용)

구현 원리

  • @OneToMany와 @ManyToOne 양방향 매핑 사용.
  • 부모 엔터티(Board) 삭제 시 연관된 댓글과 좋아요도 자동 삭제 (CascadeType.ALL 적용).

엔터티 설정

@Entity
public class Board {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;
    private String content;

    @OneToMany(mappedBy = "board", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Comment> comments = new ArrayList<>();

    @OneToMany(mappedBy = "board", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Like> likes = new ArrayList<>();

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

@Entity
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "board_id")
    private Board board;

    private String content;
}

@Entity
public class Like {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "board_id")
    private Board board;
}

게시물 삭제 시 자동으로 연관 데이터 삭제

  • CascadeType.ALL : 부모 엔터티가 삭제될 때 자식 엔터티(Comment, Like)도 함께 삭제됨.
  • orphanRemoval = true : 부모와의 연관관계가 끊긴 자식 엔터티를 자동으로 삭제.

장점

  • 삭제 로직이 간단해짐 : 부모 엔터티를 삭제하면 연관된 자식 엔터티도 자동으로 삭제됨.
  • 코드가 서비스 계층에 비해 간결하고 직관적임.

단점

  • 양방향 매핑으로 인한 N+1 문제가 발생할 수 있음.
  • 데이터가 많을 경우 성능 저하가 발생할 수 있음.
  • 양방향 연관관계로 인해 설계 복잡성이 증가함.

3. 비교 / Cascade 사용 vs 서비스 계층에서 직접 삭제

구분 Cascade 사용 서비스 계층에서 직접 삭제
연관관계 매핑 @OneToMany + @ManyToOne 양방향 매핑 필요 @ManyToOne 단방향 매핑만 사용
코드 복잡도 간단 (JPA가 자동으로 삭제 처리) 서비스 계층에서 삭제 로직을 관리
N+1 문제 발생 가능 방지 가능
성능 많은 데이터 처리 시 성능 저하 가능 성능 최적화 용이
설계의 유연성 설계가 복잡해질 수 있음 설계가 단순하고 명확

4. 예상 발생 문제점

  1. N+1 문제 발생 시
    • Cascade 방식을 사용할 경우, fetch 전략을 조정하거나 EntityGraph를 사용해 연관 데이터를 한 번에 로딩해야 합니다.
  2. 대량 데이터 삭제 성능 문제
    • 직접 삭제 방식을 사용 시, 댓글이나 좋아요가 많을 경우 배치 쿼리나 JDBC Template을 활용해 성능을 개선할 수 있습니다.
  3. 삭제 시 참조 무결성 예외 발생
    • 서비스 계층에서 댓글과 좋아요를 삭제할 때 외래키 제약조건에 의해 예외가 발생할 수 있으므로, 삭제 순서를 정확하게 관리해야 합니다.
저작자표시 비영리 변경금지 (새창열림)

'Spring' 카테고리의 다른 글

(Spring) Path Variable & Request Param 차이점  (0) 2024.10.29
(Spring) Jackson과 Spring에서의 활용  (0) 2024.10.28
(Spring) Controller & RestController란 무엇인가  (0) 2024.10.23
(Spring) DI와 IOC 이해하기  (0) 2024.10.18
(Spring) Servlet & DispatcherServlet 개념  (0) 2024.10.14
'Spring' 카테고리의 다른 글
  • (Spring) Path Variable & Request Param 차이점
  • (Spring) Jackson과 Spring에서의 활용
  • (Spring) Controller & RestController란 무엇인가
  • (Spring) DI와 IOC 이해하기
lastdove
lastdove
lastdove 님의 블로그 입니다.
  • lastdove
    lastdove 님의 블로그
    lastdove
  • 전체
    오늘
    어제
    • 분류 전체보기 (80)
      • Spring (16)
      • JAVA (17)
      • JAVA 알고리즘 (20)
      • Project (5)
      • SQL 문제풀이 (17)
      • Git&Linux (2)
      • Web development(입문) (2)
      • Sparta (1)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
lastdove
(Spring) 삭제 관련 Cascade 사용 여부에 따른 정리
상단으로

티스토리툴바