현상
- ZonedDateTime 타입의 컬럼에 ZonedDateTime.now() 값 저장시 현재 시간보다 9시간 빠른 시간으로 저장 됨
- JPA DB insert log 에서는 현재 시간으로 저장 요청을 하지만, 실제 DB에는 9시간 빠른 시간으로 저장된 것을 확인
원인
- Spring Boot 3.1 버전부터 Hibernate 6.2 버전이 적용되는데, 6.2 버전에서 OffsetDateTime, ZonedDateTime 사용시 timezone 을 다루는 방식이 변경되면서 생긴 현상
- 변경된 시간대(timezone) 정보를 다루는 방식
- 내부적으로 TimeZoneStorageType 값과 매핑하여 저장 및 조회 로직이 결정됨
- 기본값은 TimeZoneStorageType.DEFAULT
- DB 컬럼이 시간대 정보를 저장하면 시간대 정보를 함께 저장(NATIVE 와 동일)
- DB 컬럼이 시간대 정보를 저장하지 않으면 UTC 시간을 보정하여 시간 정보를 저장(NORMALIZE_UTC)
- datetime 은 시간대 정보가 없기 때문에 UTC 보정된 -9시간이 적용된 시간으로 저장됨
- TimeZoneStorageType.DEFAULT?
해결 방법
- spring.jpa.properties.hibernate.hibernate.timezone.default_storage를 NORMALIZE로 설정
→ 시간대 정보를 6.2 이전 버전과 동일한 방식으로 설정하는 옵션으로, 해당 옵션 설정시 DataSource 에 설정한 시간대(serverTimezone=UTC) 또는 JVM 기본 시간대 정보를 사용하게 됨 - 위와 같은 이유로 ZonedDateTime 컬럼에 @TimeZoneStorage(TimeZoneStorageType.NORMALIZE) 설정TimeZoneStorageType? → https://docs.jboss.org/hibernate/orm/6.2/javadocs/org/hibernate/annotations/TimeZoneStorageType.html
주의사항
- ZonedDateTime(or OffsetDateTime) & datetime 사용시
spring.jpa.properties.hibernate.timezone.default_storage:NORMALIZE 설정과
spring.jpa.properties.hibernate.jdbc.time_zone:UTC 설정을 함께 사용하면 -9시간 된 시간으로 저장될 수 있음- ZonedDateTime.now() 값 조회 → 현재 시간
- spring.jpa.properties.hibernate.timezone.default_storage:NORMALIZE 설정 → 현재 시간을 UTC로 변환
- spring.jpa.properties.hibernate.jdbc.time_zone:UTC 설정 → UTC 변환된 시간 그대로 데이터베이스에 저장
- 최종 저장결과 한국 시간 기준 -9시간 된 시간 정보가 저장됨
- 다만 hibernate.jdbc.time_zone 설정을 Asia/Seoul 로 하면 정상적으로 저장됨
반응형