본문 바로가기
관리자

Programming-[Backend]/JPA

[TIL] Soft Delete hibernate, @SQLRestriction

728x90
반응형

 

배경

JPA에서 Soft delete 방식을 적용하기 위해 전체 엔티티의 상위 엔티티에 deleted_at 컬럼을 적용하고 상속받는 구조로 만든다. 그러나 이렇게 처리했을 때, 모든 엔티티들을 처리하는 쿼리문에서 deleted_at을 신경써줘야한다는 문제점이 발생한다.

@Getter
@Setter
@MappedSuperclass
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Audited
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntityAbstract implements Serializable {
    @NotAudited
    @Column(name = "deleted_at")
    protected LocalDateTime deletedAt;

}

 

 

방안

아래 참조 글을 보면, @SQLRestriction을 사용하는 방법에 대해 장단점 분석을 한다.

https://jaeseo0519.tistory.com/375

 

모든 엔티티 위에 어노테이션을 선언하는 것이다.

@SQLRestriction("deleted_at IS NULL")

 

 

이렇게 처리하면 언제나 deleted_at 값이 있어서 soft delete된 항목들은 제외하고 쿼리가 나간다. 따라서 JPA, Querydsl 등에서 where절에 일일이 deleted_at 조건을 처리해줄 필요가 없게 된다.

 

다만 나는 이 기능을 사용하지 않고 일일이 deleted_at 구문을 추가해주기로 했다.

  • deleted_at 항목들을 조회하고, 다시 살려야할 부분들이 존재할 때(즉 삭제를 취소할 때) @SQLRestriction을 우회하는 방법을 찾아서 적용해야한다. 이 때 EntityManager를 직접 불러와서 처리해야한다. 당장은 그럴 일이 없다고 생각할 수 있겠지만 프로젝트가 점점 더 커짐에 따라서 이 비용이 많이 증가하게 된다.
  • 여러 엔티티를 join 방식으로 참조하는데, 특정 엔티티는 삭제되지 않았으면서 다른 엔티티는 삭제된 경우 등의 복합적인 쿼리가 필요할 때, 이를 커스텀하면서 처리하는 것이 오히려 불편해진다. 그리고 내가 아닌 다른 개발자나 사용자가 이를 계속해서 인지하고 있어야한다. 그냥 인지적 관점에서 DB상 deleted_at이 있고 그것을 처리해야한다는 것을 동의하면 되는데, @SQLRestriction을 적용해놓으면 참조 글처럼 도메인의 순수 관심사에 deleted_at이라는 고수준 관심사가 끼어버린 꼴을 초래하게 되는 것 같다.
728x90
반응형