[Java/Spring] soft delete 쉽게하기

HANJIN·2022년 3월 3일
2

Java/Spring

목록 보기
1/1
post-thumbnail

Issue

개발하면서, 데이터의 혹시 모를 유실을 방지하기 위하여, 데이터의 hard delete 없이 하고 있습니다.
nestjs+typeorm을 사용하다가 spring으로 기술 스택을 전환하면서, hibernate에서는 soft delete에 대한 메소드가 준비되어있지 않았고 그래서 모든 데이터를 가져올 때 조건절에 deleted_at을 주고 사용하고 있었죠

그러다 보니 자연스럽게 개발중에 JOIN 쿼리를 사용할 시 deleted_at 조건이 빠진다거나 하는 미스가 자주 발생하게 되었고,
이 문제를 해결하기 위해서 개발자가 신경쓰지 않아도 알아서 soft delete된 데이터를 걸러주고, delete시 soft delete로 바꾸어주는 방식을 적용하는게 좋겠다는 생각이 들었습니다.

사용중인 기술

  • Spring Data JPA를 적용하여 Repository 패턴을 사용중

Goal

  • 조회 시 soft delete 된 데이터는 제외되어야한다.(Join 포함)
  • 삭제 시 soft delete 되어야 한다.

Solution

@Where

리서치 중 hibernate가 제공하는 @Where 어노테이션에 대하여 알게되었습니다.

어노테이션이 정의 된 파일을 같이 볼까요?

해당 엔티티 or 엔티티 컬렉션을 조회할 때 사용할 where 절을 정의.
해당 구문은 SQL로 쓰여져있어야함.
일반적인 use case는 soft delete.

저의 목적을 달성하기에 아주 적합한 기능을 가진 어노테이션이네요

이 어노테이션은 다음과 같이 사용합니다.

@Entity
@Where(clause = "deleted_at IS NULL")
class Person {
	@Id
    private Integer id;
    
    ...
}

엔티티를 이렇게 정의하면, id를 이용하여 엔티티를 가져왔을 때 자동으로 where절에 deleted_at IS NULL 이라는 SQL구문을 추가해주기때문에, 별다른 노력없이 soft delete된 데이터는 조회하는 데이터에 포함되지 않게 됩니다.

#####단일 엔티티, 컬렉션, Join시 모두 적용됩니다###

첫번째 목표를 달성했네요. 이제 두번째 목표는 어떻게 달성할까요?

@SQLDelete

해당 어노테이션 또한 hibernate가 제공합니다.

파일부터 같이 보시죠

엔티티 / 컬렉션을 삭제하기 위한 커스텀 SQL 구문

말 그대로 delete시 적용할 커스텀한 SQL 구문을 명시할 수 있다~~이겁니다.

우리는 soft delete를 해야하고, 일반적으로 delete할 때 deleted flag 혹은 delete_at 타임스탬프등을 남겨 해당 데이터가 삭제 된 데이터임을 표시합니다.

그렇다면 SQL구문으로 해당 작업을 수행하기 위해서는 DELETE 구문 대신 UPDATE 구문을 사용해야겠네요. 또한, 위 어노테이션에 구문을 지정할 수 있으니 이렇게 처리할 수 있습니다.

@Entity
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE person SET deleted_at = CURRENT_TIMESTAMP where id = ?")
class Person {
	@Id
    private Integer id;
    
    ...
}

위 코드를 적용하면 이제 엔티티를 삭제할 때 row를 삭제하지않고 해당 엔티티를 대상으로 명시한 SQL문을 사용하게 됩니다.

주의

  • SQL문 기준으로 작성해야합니다.(엔티티의 camelCase 프로터피가 아닌, 실제 컬럼이름, 실제 데이터베이스에 적용 가능한 쿼리를 작성해야함)
  • hibernate, Spring Data JPA등 라이브러리가 설치되어있어야합니다.
  • @SQLDelete 예제의 ? 에는 해당 엔티티에 @Id 어노테이션을 사용한 프로퍼티의 값이 사용되므로, pk를 id라는 컬럼으로 사용하시는게 아니라면, SQL문을 커스터마이즈해서 사용하셔야합니다!

다음 포스팅에서도 만나요!

피드백, 질문은 언제나 감사하게 받겠습니다

profile
소프트웨어 엔지니어.

0개의 댓글