이슈 주제 : 객체형 필드 사용 시 Dirty Checking이 발생하는 경우
얼마전 회사에서 제법 큰 서비스 리뉴얼 배포를 진행했는데, 조회 로직에서 알수 없는 update query 가 발생하는 이슈를 파악했다.
JPA가 이슈를 일으킨 것인데 (정확히 말하자면 JPA를 잘못쓴 개발자(It's me)...) 객체형 필드를 사용한 특정 Entity 에서만 이슈를 발생시키고 있는 것을 파악했다.
이슈를 파악하고 해결한 과정은 아래와 같다.
<이슈>
객체형 필드를 Entity에 사용한 경우 JPA 트렌젹센이 끝나는 시점에 JPA Dirty Cheaking 발생하여 의도하지 않은 Update Query 를 진행한다.
*객체형 필드 : Class를 객체로 사용하는 필드를 말한다.
<이슈 발생 원인>
JPA는 Entity 조회시 영속성 컨텍스트에 데이터를 복사해 사용한 후 트랜젹션 종료 시점에 원본과의 컬럼을 하나 하나 비교한 후 update 유무를 결정한다.
이때, Entity에 필드의 타입에 객체형 필드를 사용한 경우,
Java에서는 객체의 equals를 override하지 않으면 레퍼런스 비교를 하기 때문에 같은 값을 갖고 있더라도 신규 생성된 객체의 경우 원본 객체 비교시 변경된 것으로 판단한다. -> update 문 발생
<해결방법>
객체형 필드로 사용한 Class 에 equals, hsahCode 를 orverride 한다.
(또는 lombok @EqualsAndHashCode 사용)
<객체형 클래스를 사용한 경우에도 발생하지 않는 경우>
- 불변객체인 경우
-> 불변객체인 경우, 객체가 변하지 않기 때문에 원본 필드와 영속성 필드를 비교해도 같음 - @Embedded 타입인 경우
-> 임베디디 타입일 경우, 실제 비교를 클래스 객체가 아닌 클래스 내부의 필드들을 대상으로 각각 비교를 진행
<referense>
https://jojoldu.tistory.com/536