[JPA] 이해하고 사용하는 Dirty checking

Eunbi Lee·2026년 6월 14일

SeaVantage

목록 보기
20/20
post-thumbnail

Background

최근 CRUD API 를 뚝-딱 만들어야 했던 업무가 있었다.

이때, hard-delete 가 아닌 soft-delete 로 처리되어야 하는 API 를 보고, 보자마자 떠오른 생각은 update 보다 더 update 다운 DELETE API다! 라는 생각이었다.

따라서, 바로 Dirty Checking 을 사용해봐야겠다 싶었다.

In Past Using

Dirty checking 개념 자체는 상당히 유명하기도 하고, 이전에 개발을 했을 때에도 사용한 적 있던 JPA concept 였다.

  • 하지만, JPA 를 막 쓰기 시작한 때에 사용했던 터라 기억에 잘 남지 않았기에 복습 겸 사용하게 되었다.

Dirty checking

Dirty checking 은 Entity 를 조회했을 때의 snapshot 과 transaction 이 끝날 시점의 Entity status 가 다를 경우, Update query 를 통해 변경 사항을 반영하는 concept 이다.

Example

이번에 개발할 soft-delete DELETE HTTP method 가 딱 적합한 예시이다.

먼저 프로세스는 다음과 같다.

Process

  1. Path variable 의 id 를 통해, 해당 Entity 가 존재하는지 조회한다.
  • 존재하지 않을 경우, EntityNotFoundException
  1. 존재할 경우, 해당 Entity 의 soft-deleting 처리를 할 column 에 대해 value 를 변경한다.
  • ex. is_deleted = false -> true.

Code

프로세스는 간단했다. 그러면 코드로 보면 어떨까?

  1. soft-delete 를 시도할 n 개의 id 를 request body 로 담는다.
    @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
                        )
                );
    }
  1. id 를 기반으로, 해당 Entity 들이 DB 에 존재하는지 확인한다.

@Transactional
    public void deleteRoutings(
            DeleteOptimalRoutingV2Request request,
            String userId
    ) {
    
..
    
long count = optimalRoutingV2Repository.countByUserIdAndIdIn(userId, ids);

..

}
  1. 그리고, 변경하고자 하는 column 에 대해 value 값을 변경한다.
...

public void markAsDeleted() {
        this.isDeleted = true;
    }
    
...

그리고, 이렇게만 작성하고 실행하면, 실제로 application 상에서 update query 를 요청하는 걸 log 로 확인할 수 있다.

❗ 단, 이 편리한 Dirty Checking 의 가정은 Entity 가 Transaction 으로 관리가 되고 있다는 전제하다.

Concept

이때, log 에서 볼 수 있듯이, 해당 update query 는 Entity 의 모든 field 에 대해 query 를 작성하므로, 특정 field 에 대해서만 작성하고 싶을 경우는 따로 handling 이 가능하다.

관련 concept 에 대해선 자세히 작성된 좋은 글이 존재한다.

profile
안녕하세요, 개발자 비비입니다.

0개의 댓글