논리적 삭제 soft delete

곽현민·2026년 1월 12일

부모 엔티티와 자식 엔티티간에 fk연결 제약조건 탓에 부모 엔티티의 삭제가 불가한 상황을 조우했다.
삭제에는 논리적 삭제와 물리적 삭제가 존재한다.

Soft delete and Hard delete

Soft delete

논리적 삭제는 실제로 삭제가 되진 않는다.
말그대로 논리적으로 보았을 때, 삭제가 된 것으로 보는 것이다.
데이터의 상태를 변화시켜 삭제된 데이터와 남은 데이터의 차이를 두어 삭제되었다고 인식하는 것이다.

예를 들어 deleted라는 컬럼은 boolean의 값을 지닌다.
이때, true라면 삭제된 것, false라면 삭제되지 않은 것으로 인식하게 만드는 것이다.

이것이 논리적 삭제다.

논리적 삭제를 통해 실제로 삭제를 하는 것이 아닌 데이터의 상태를 변화시키는 것이기 때문에, 데이터는 보존된다.

장점은 데이터의 복구적인 측면에서 매우 좋다
단점은 데이터의 양이 많아질 수록 삭제된 데이터의 공간 차지가 많아진다.

Hard delete

물리적 삭제는 우리 알고 있는 데이터를 실제로 삭제하는 것이다.
데이터가 굉장히 중요한 자산이기 때문에 쉽게 삭제하지 못하게 하는 방향성을 잡는 것이 중요할 듯하다.

때에 따라 논리적 삭제와 물리적 삭제를 적절히 사용하는 것이 좋을 듯 하다.


Spring soft delete

스프링에서의 논리적 삭제를 구현해볼 것이다.

논리적 삭제를 도와줄 어노테이션을 소개하겠다.
@SQLDelete
@SQLRestriction
@SoftDelete

@SQLDelete

논리적 삭제의 주요 기능을 도와주는 어노테이션이다.

@SQLDelete(sql = "UPDATE table SET deleted = true WHERE id = ?")

JPA의 물리적 삭제 기능인 delete()가 실행 시 실제로 데이터를 삭제하지 않고, deleted의 상태를 true로 바꿔 상태를 업데이트 시켜준다.

상태를 업데이트 했다고 끝이 아니다.

@SQLRestriction

데이터를 조회할 때, 삭제된 데이터를 필터링해야 비로소 우리는 데이터를 논리적으로 삭제했다고 할 수 있다.
그 필터링을 도와주는 어노테이션이다.

@SQLRestriction("deleted = false")

deleted의 상태가 false인 데이터들만 조회한다는 뜻을 지녔다.

위 두 가지의 어노테이션을 이용하여 데이터의 상태를 변화시키고 조회 시 필터링을 통해 논리적 삭제를 구현할 수 있다.

하지만 여기서 의문점이 하나 들 수 있다.
위 두 가지의 어노테이션으로 논리적 삭제를 구현했는데, @Softdelete는 어떤 역할인가?

@Softdelete

@Softdelete는 위의 두 어노테이션의 기능을 하나로 해결할 수 있는 어노테이션이다.

@Softdelete

정말 간단하게 이 어노테이션 하나를 통해 삭제 시 상태 변화와 조회 시 필터링의 기능을 구현할 수 있다.

그리고 추가적으로 이 어노테이션은 따로 별도의 필드를 선언하지 않아도 자동으로 매핑해준다. columnname의 default값은 deleted다.

이러한 매력적인 점 때문에 @Softdelete를 선택하여 코드를 작성하던 도중

한 가지 오류를 직면하게 된다.

그건 바로,,,

@Softdelete가 LAZY 로딩 방식을 지원하지 않는다는 것이다.
따라서 LAZY 로딩 방식을 택하기 위해선 @SQLDelete와 @SQLRestriction을 사용해야 한다.
@Softdelete를 사용하고 싶다면 EAGER 로딩 방식으로 택해 진행해야 한다.

0개의 댓글