[Spring] JPA Soft Delete 간단하게 적용하기

오형상·2023년 8월 12일
0

Spring

목록 보기
5/9
post-thumbnail

✅ Hard Delete vs Soft Delete: 데이터 삭제 방식 비교

📌 Hard Delete(물리 삭제)

  • SQL의 DELETE 명령어를 활용하여 데이터를 물리적으로 제거하는 방식입니다.
  • 실제로 디스크에서 데이터가 영구적으로 삭제되어, 디스크 공간을 확보할 수 있습니다.
  • 삭제된 데이터를 복원하기 어려우며, 복구가 불가능합니다.
  • JPA의 기본 Delete 동작은 Hard Delete입니다.

📌 Soft Delete(논리 삭제)

  • SQL의 UPDATE 명령어를 활용하여 특정 플래그나 상태 컬럼을 변경하여 삭제 여부를 표시하는 방식입니다.
  • 데이터는 물리적으로 삭제되지 않으므로, 디스크 공간 사용량이 증가합니다.
  • 조회 시 삭제 여부를 고려하여 데이터를 판별하므로, 조회 성능이 저하될 수 있습니다. 또한 실수로 삭제된 데이터가 조회될 가능성이 있습니다.
  • 삭제 여부 표시 컬럼을 변경하면 손쉽게 데이터의 삭제 여부를 변경할 수 있습니다.

❓ 왜 Soft Delete를 구현하는가?

삭제된 데이터를 나중에 활용해야 하는 경우가 있습니다. 예를 들어, 통계 작업이나 복구 과정 등에서 활용될 수 있습니다.
물리적으로 삭제된 데이터는 복원이 불가능하므로, 필요한 경우에 대비하여 Soft Delete를 구현하는 것이 유용합니다.

✅ JPA Soft Delete

📌 @SQLDelete 어노테이션

첫 번째로 살펴볼 어노테이션은 @SQLDelete입니다. 이 어노테이션을 사용하면 Delete 쿼리가 발생할 때 지정한 특정 쿼리로 대체되어 실행됩니다.

Delete 쿼리 대신에 해당 어노테이션을 사용하여 Update 쿼리가 발생하게끔 설정합니다. 이러한 쿼리는 트랜잭션이 종료되는 시점에 변경되어 사용됩니다.

📌 @Where 어노테이션

두 번째로 살펴볼 어노테이션은 @Where입니다. 이 어노테이션은 Select 쿼리가 실행될 때 기본적으로 정의한 where 구문이 추가되어 실행됩니다.

간단히 말하면, 이 어노테이션을 사용하면 해당 엔티티를 조회하는 모든 Select 쿼리에 where deleted_at = null 같은 구문이 추가됩니다. 이로써 삭제되지 않은 엔터티만이 조회되어 가독성을 높이고 예상치 못한 삭제 상황을 방지할 수 있습니다.

✅ @SQLDelte, @Where 적용 및 테스트

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE post SET deleted_at = CURRENT_TIMESTAMP WHERE post_id = ?")
public class Post extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id")
    private Integer id;

    private String title;

    private String body;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

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

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

	//.. 중략

📌 삭제 테스트

delete 대신 update가 나가고있다.

📌 조회 테스트

where절에 deleted_at IS NULL이 추가되어 삭제되지 않은 것을 조회한다.

1개의 댓글

comment-user-thumbnail
2023년 8월 12일

좋은 정보 감사합니다

답글 달기