생각을 공유하기 위해 쓴 글입니다. 정보 전달이 아닙니다!
JPA
를 공부하다 보면, JPA
의 영속성 컨텍스트는 변경 감지를 통해 Entity를 update
한다고 합니다. 변경 감지에 대해서 잘 모르시는 분들께 간단히 설명 드리겠습니다.
이처럼, 영속성 컨텍스트가 변경 감지를 통해서 Entity의 상태를 추적하기 때문에, 개발자 입장에서 직접 entity.update()
메서드를 날리지 않아도 트랜잭션이 커밋될 때 JPA가 자동으로 update 쿼리문을 날려주는 것이죠.
그런데, 이러한 변경 감지는 언제 발생하는 걸까요? 저는 트랜잭션이 커밋
이 일어나는 시점에 변경 감지가 발생한다고 알고 있었습니다. 정확하게는 트랜잭션이 커밋되어 entityManager.flush()
가 호출되는 시점에 영속성 컨텍스트의 SQL 지연 저장소에 저장되어 있는 쿼리문들을 비움과 동시에 변경 감지가 일어나는 거라고요.
그런데 Baeldung
사이트에서는 다음과 같이 설명하고 있습니다.
Persistence context keeps track of any changes made into a managed entity. If anything changes during a transaction, then the entity is marked as dirty. When the transaction completes, these changes are flushed into persistent storage.
- 영속성 컨텍스트는 영속된 엔티티에 대하여 어떠한 변경 사항이라도 발생하면, 계속
dirty
로서 기록해둔다 (변경 감지). 트랜잭션이 종료될 때, 이러한 변경 사항들은 DB에 flush된다.
출처: https://www.baeldung.com/jpa-hibernate-persistence-context
위와 저는 생각이 약간 다릅니다.
위와 견해가 다른 또 다른 아티클을 한번 보시겠습니다.
By default Hibernate checks all managed entity properties. Every time an entity is loaded, Hibernate makes an additional copy of all entity property values. At flush time, every managed entity property is matched against the loading-time snapshot value:
출처: https://vladmihalcea.com/the-anatomy-of-hibernate-dirty-checking/
Hibernate의 변경 감지 로직에 대한 설명과 그림입니다. Hibernate가 엔티티가 영속될 때 모든 속성 값들을 저장하고 있다가, 매번 엔티티가 로딩될 때 스냅샷을 계속 떠놓습니다. 그리고 flush 상황에서 변경 감지를 실행한다는 것을 알 수 있습니다. (도표에서도 시작점이 flush 인 것을 확인할 수 있습니다.)
즉, 변경 감지는 변경이 발생할때마다 일어나는 것이 아니라, flush()가 호출되는 상황에 일어난다... -> 라는 것이 제 생각입니다.
틀린 점이 있거나, 혹시 정답을 알고 계시다면 댓글로 남겨주시면 감사하겠습니다!!
Inflearn - 자바 ORM 표준 JPA 프로그래밍 - 기본편
https://www.inflearn.com/questions/685350?re_comment_id=221866 (제 질문과 답변)
https://vladmihalcea.com/the-anatomy-of-hibernate-dirty-checking/