JPA
[JPA] @SQLRestriction으로 soft delete 구현하기
kkang._.h00n
2025. 12. 21. 21:00
개요
데이터 삭제 정책이 soft delete라면, 데이터 조회 시 delete 상태 여부를 확인하는 조건을 일일이 넣어주어야 할 것이다.
@SQLRestriction 어노테이션을 통해 SQL의 where절에 delete 상태 여부를 체크하는 조건을 넣는 방법을 소개하려 한다.
문제
코드를 살펴보자. 먼제 Hospital 엔티티이다.
@Entity
@Table(name = "hospitals")
class Hospital(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val name: String,
...
//삭제가 된 상태라면, 해당 필드에 값 존재
var deletedAt: LocalDateTime? = null
) : BaseTime()
엔티티에서는 삭제 시간을 기록하는 deletedAt이 있다. 해당 필드의 값이 존재한다면 그 시간에 삭제가 된 것이고, 존재하지 않는다면 아직 삭제된 상태가 아니다.
해당 프로젝트에서는 데이터가 삭제 처리되었을 경우 보여주지 않아야 한다. 그렇다면 모든 Hospital 목록을 보여주어야 하면 정책에 따라 아래처럼 쿼리를 작성해야 할 것이다.
interface HospitalRepository : JpaRepository<Hospital, Long> {
@Query("""
select h
from hospital h
where h.deletedAt is null
""")
fun findAllWithOutDeleted(@Param("id") id: Long)
}
이렇게 되면 기능이 추가될 때마다 findById()나 메서드쿼리 같은 Spring Data Jpa에서 제공하는 기능을 사용하지 못하고 쿼리를 재작성 해야 할 것이다.
적용
//어노테이션 적용
@SQLRestriction("deleted_at IS NULL")
@Entity
@Table(name = "hospitals")
class Hospital(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val name: String,
...
var deletedAt: LocalDateTime? = null
) : BaseTime()
엔티티 조회 시 SQL의 공통된 조건을 적용해야 한다면, @SQLRestriction의 조건을 넣어주면 간단하게 해결된다.
결과

findAll() 메서드를 통한 조회 시, 설정한 조건이 where절에 적용된 것을 볼 수 있다!