JPA는 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장 해놓는다. 이것을 흔히 “스냅샷(Snapshot)”이라고 한다. 그리고 Flush 시점에 스냅샷의 Entity(Before)과 Flush 되는 시점의 Entity(After)를 비교해서 변경된 엔티티를 찾는다.

업데이트 여부 판단 순서

  1. 트랜잭션을 Commit하면 EntityManager. 내부에서 먼저 flush 메서드가 호출된다.
  2. 스냅샷의 Entity(Before)와 현재 Entity(After)를 비교해서 변경된 Entity를 찾는다.
  3. 변경된 엔티티가 있으면 수정 쿼리(Update Query)를 생성해서 쓰기 지연 SQL 저장소에 보낸다.
  4. 데이터베이스 트랜잭션을 Commint 한다.

실제 쿼리는 우리가 생각하는 것 처럼, 변경된 컬럼만 포함된 Query가 실행되지 않고 모든 필드가 업데이트 되는 Query가 실행된다. 이렇게 되면 DB에 보내는 데이터 전송량이 증가한다는 단점도 존재하지만, 장점 또한 존재한다. 항상 동일한 Update Query가 실행되고 DB는 이전에 한번 파싱된 쿼리를 재사용할 수 있다.

하지만, 필드의 수가 너무 많다면 캐싱에 대한 장점 보다는 데이터 전송량을 줄이는 것이 더 좋다고 판단 할 수 있다. 이럴 때는 @DynamicUpdate를 Entity 클래스에 선언해주면 변경된 필드만 추가된 Update Query가 실행된다.아