개요
데이터 삭제 정책이 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절에 적용된 것을 볼 수 있다!
'JPA' 카테고리의 다른 글
| [JPA] saveAll() 문제점과 JDBC를 통한 해결 (0) | 2026.01.14 |
|---|---|
| [JPA] 프록시 객체와 OneToOne 양방향 관계 이슈 (0) | 2025.12.21 |
| [JPA] 영속성 컨텍스트와 flush 시점 (0) | 2025.12.20 |
| [JPA] 테스트를 통해 알아본 JPA와 영속성 컨텍스트 (0) | 2024.03.15 |
| [Query DSL] Expressions를 사용하여 여러 값에 대한 존재 여부 확인하기 (0) | 2023.12.14 |