
최근 CRUD API 를 뚝-딱 만들어야 했던 업무가 있었다.
이때, hard-delete 가 아닌 soft-delete 로 처리되어야 하는 API 를 보고, 보자마자 떠오른 생각은 update 보다 더 update 다운 DELETE API다! 라는 생각이었다.
따라서, 바로 Dirty Checking 을 사용해봐야겠다 싶었다.
Dirty checking 개념 자체는 상당히 유명하기도 하고, 이전에 개발을 했을 때에도 사용한 적 있던 JPA concept 였다.
Dirty checking 은 Entity 를 조회했을 때의 snapshot 과 transaction 이 끝날 시점의 Entity status 가 다를 경우, Update query 를 통해 변경 사항을 반영하는 concept 이다.
이번에 개발할 soft-delete DELETE HTTP method 가 딱 적합한 예시이다.
먼저 프로세스는 다음과 같다.
EntityNotFoundExceptionis_deleted = false -> true.프로세스는 간단했다. 그러면 코드로 보면 어떨까?
@DeleteMapping
@PreAuthorize("hasAnyRole('...')")
public ResponseEntity<BasicRestResponse<Void>> delete(
@RequestBody @Valid DeleteOptimalRoutingV2Request request
) {
..
optimalRoutingServiceV2.deleteRoutings(request, userId);
..
return ResponseEntity.status(NO_CONTENT)
.body(BasicRestResponse.ofSuccessResponse(
NO_CONTENT,
null
)
);
}
@Transactional
public void deleteRoutings(
DeleteOptimalRoutingV2Request request,
String userId
) {
..
long count = optimalRoutingV2Repository.countByUserIdAndIdIn(userId, ids);
..
}
...
public void markAsDeleted() {
this.isDeleted = true;
}
...
그리고, 이렇게만 작성하고 실행하면, 실제로 application 상에서 update query 를 요청하는 걸 log 로 확인할 수 있다.

❗ 단, 이 편리한 Dirty Checking 의 가정은 Entity 가
Transaction으로 관리가 되고 있다는 전제하다.
이때, log 에서 볼 수 있듯이, 해당 update query 는 Entity 의 모든 field 에 대해 query 를 작성하므로, 특정 field 에 대해서만 작성하고 싶을 경우는 따로 handling 이 가능하다.
관련 concept 에 대해선 자세히 작성된 좋은 글이 존재한다.