과제 프로젝트를 kotlin 과 spring boot로 진행하던 도중 직면한 문제입니다.
먼저 원인은 Lecture 엔티티 속 이 코드입니다. 스케쥴 List를 (ex. {월 2~4시, 수 5~6시}) 가지고 있어야 하기 때문에 칼럼에 추가하였습니다.
Lecture.kt
@Convert(converter = JpaJsonScheduleConverter::class)
@Column(name = "SCHEDULE")
var schedule: List<Schedule>? = null
Schedule.kt
class Schedule (
var day: String? = null,
var startTime: String? = null,
var endTime: String? = null,
)
Dirty Checking을 하는 것 같아 찾아 보니 다음과 같이 이해할 수 있었다.
Hibernate는 트랜잭션 범위에서 Entity를 조회할 경우, 조회시점의 Entity 복사본을 만들고,
더티 체킹 시, 영속성 컨텍스트에 있는 객체가 해당 복사본과 일치하는 지 비교하게 되는데,
Objects.equals를 사용해서 엔터티에 존재하는 각 필드가 전부 같은지 비교를 한다.
근데 Objects.equals()를 오버라이딩하지 않으면 각 필드를 비교할 수 없어서 Reference를 비교하게 되는데,
내 Lecture 엔터티 속의 Schedule class는 equals가 오버라이딩되지 않아서 레퍼 체크를 하고 있어서 기본적으로 엔터티 복사본과 다르게 되어, 업데이트 쿼리가 나갔던 것이다.
해결방법
Schedule 클래스에 data 키워드를 추가하여 equals 를 코틀린에서 자동 구현하게 해서 해결!
사실 해결방법은 무지 쉽고, 원인 파악이 중요했던 것이다.