게시판을 관리하는 백오피스 프로젝트를 진행하며 데이터의 삭제에 대한 고민을 했었는데, 실무에서 데이터 = 회사의 자산이기 때문에 삭제에 대해 엄청나게 보수적이라는 말을 들었다. 그래서 보통 Soft-delete 방식으로 데이터를 삭제 '처리' 한다고 한다.
지난 Newsfeed 프로젝트에서도 한 팀원분의 제안으로 is_deleted 필드를 추가하여 기본값은 Null, 삭제되면 삭제된 시간을 저장하는 방법으로 Soft-delete 를 구현했었다.
그리고 이 내용을 포함해서 Query를 짜기 위해 QueryDSL을 작업하시며 꽤나 고생하셨을 것 같았다.
지난 프로젝트를 참고하여 시간값으로 할 수도 있었지만 이번엔 간단하게 Boolean 타입으로 먼저 구성해 보았다.
import org.hibernate.annotations.Where
@Entity
@Table(name = "boards")
class BoardEntity(
@Column(name = "created_at")
val createdAt : LocalDateTime = LocalDateTime.now(),
@Column(name = "is_deleted")
var isDeleted : Boolean = false,
...
이후 Controller 에서 Delete 메서드 호출 시 DeleteMapping이 아닌 PutMapping 으로 받아와서 is_deleted 값을 true 로 바꿔주는 과정만 작성하였다.
하지만 이렇게 되면 다른 메서드에서 호출 시 (예를 들어 findAll() )결과에 포함되는 것은 마찬가지이기 때문에 원래대로라면 WHERE is_deleted = false 라는 조건을 추가해주어야 한다.
Entity에 @Where 어노테이션을 붙이는 것으로 해당 Entity의 모든 Query 에 자동으로 Where 조건을 적용해줄 수 있게 된다.
따라서 아래와 같이 작성하면 is_deleted 가 true 인 항목은 무시하게 되는 것이다.
@Entity
@Where(clause = "is_deleted = false")
@Table(name = "boards")
class BoardEntity(
@Column(name = "created_at")
val createdAt : LocalDateTime = LocalDateTime.now(),
@Column(name = "is_deleted")
var isDeleted : Boolean = false,
...
단, 이렇게 되면 모든 Query에 적용되기 때문에 관리자 모드 등에서 soft-delete 된 항목만 확인하고 싶을 땐 다른 방법을 찾아 적용해야 한다는 단점이 있다.