[백업][가리사니] 스프링 부트 3.1.0 이후 offsetdatetime, zoneddatetime 의 타임존 오류
hibernate, spring

이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.

서론

운영하고 있던 사이트의 Spring Boot 를 3.0.7 에서 3.1.0 으로 업그레이드를 했다.

그러자 바로 시간이 이상하다는 글이 올라왔다. 데이터베이스를 확인하니 upd_dt가 거꾸로 간 것이다.

설명

고친 것이 버전밖에 없었기에 버전을 롤백하니 정상적으로 동작하였다.

무엇이 문제였을까?

나는 바로 버그리포트를 작성하였다. https://github.com/spring-projects/spring-data-jpa/issues/3035 하이버네이트 버전을 6.2 미만으로 내려보라고 하였고 그대로 하니 문제가 해결되었다.

hibernate 6.2 버전에서 뭔가 변경된 것이다.

얼마 뒤 댓글이 달렸고 새로운 사실을 알게되었다. 하이버네이트 측에서 OffsetDateTime, ZonedDateTime 의 기본 동작을 변경 한 것이었다.

어떻게 바뀌었고 주의할 점이 무었일까?

참고: https://thorben-janssen.com/hibernate-6-offsetdatetime-and-zoneddatetime/

# spring boot 의 설정 기준으로 아래 옵션이 추가되었다.
spring.jpa.properties.hibernate.timezone.default_storage: 

# 값은 아래와 같다.
NATIVE
NORMALIZE (Spring Boot 3.1.0[Hibernate 6.2] 미만 버전의 기본값)
NORMALIZE_UTC (이후 기본값)
COLUMN
AUTO

NORMALIZE, NORMALIZE_UTC 비교

  • 서버 시간 +09:00 / DB시간 +09:00 가정
  • OffsetDatetime 2023-07-04 10:00:00+09:00 입력.
    • NORMALIZE : 이전 기본값
        # Timezone 있는 DB - PostgreSQL
        OffsetDatetime -> DB: 2023-07-04 10:00:00+09:00 
        DB -> OffsetDatetime: 2023-07-04 10:00:00+09:00
      
        # Timezone 없는 DB - MySQL, MariaDB
        OffsetDatetime -> DB: 2023-07-04 10:00:00
        DB -> OffsetDatetime: 2023-07-04 10:00:00+09:00
      

      _

    • NORMALIZE_UTC : 최신버전 기본값
        # Timezone 있는 DB - PostgreSQL
        OffsetDatetime -> DB : 2023-07-04 01:00:00+00:00 
        DB -> OffsetDatetime: 2023-07-04 01:00:00+00:00
      

      설명 그림에서 보면 타임존이 00:00 으로 바뀌어서 DB에 들어간 것을 확인할 수 있다.

        # Timezone 없는 DB - MySQL, MariaDB
        OffsetDatetime -> DB : 2023-07-04 01:00:00
        DB -> OffsetDatetime: 2023-07-04 01:00:00+09:00
        문제발생!!!
      

      하이버네이트 쪽에선 이것을 버그라고 생각하지 않는 것 같지만. MySQL같이 타임존이 없는 DB의 경우는 OffsetDateTime, ZonedDateTime 사용시 NORMALIZE 값을 사용해야 할 것이다.

참고

  • https://docs.jboss.org/hibernate/orm/6.2/migration-guide/migration-guide.html#ddl-offset-time
  • https://thorben-janssen.com/hibernate-6-offsetdatetime-and-zoneddatetime/