개발/Java

Spring Boot 업그레이드 이후 운영 환경에서 발생한 Dialect 이슈 정리

반응형

개요

보안 및 정책 변경 이슈로 인해 기존 서버의 스프링 버전을 2.4.2 → 2.7.11로 업그레이드했다.
업그레이드 후 테스트 코드(커버리지 약 80%)를 작성해 검증했고, 약 한 달간 개발/스테이징 환경에서 실제로 서비스를 띄워 충분히 테스트를 진행해 문제없음을 확인했다.

 

하지만 운영 배포에서 예상하지 못한 장애가 발생했다.


문제

운영 배포 후 모든 서버에서 JPA Repository 실행 시 테이블을 찾지 못하는 오류가 발생했다.
운영 환경은 jpa.hibernate.ddl-auto: validate 설정이었고, Hibernate 의 스키마 검증 단계에서 공통적으로 아래 오류가 발생했다.

missing table

 

긴급하게 원복한 후 원인 분석을 시작했다.


원인

개발/스테이징에서는 문제가 없었지만 운영에서만 오류가 발생하길래, 환경 차이 중심으로 분석을 진행했다.
DBA를 통해 각 환경의 DB 설정을 비교해 보니 다음 차이가 있었다:

  • 개발/스테이징: 대소문자 구분 없음 (Case-Insensitive)
  • 운영: 대소문자 구분 (Case-Sensitive)

처음에는 단순한 설정 차이라고 생각했지만 실제 원인은 Hibernate Dialect 의 변화였다.

업그레이드 이전에는 기존 Dialect 를 사용하고 있었다: org.hibernate.dialect.MySQL5InnoDBDialect

하지만 Spring Boot 2.7 / Hibernate 5.6 환경에서는 이 Dialect 가 예전과 다르게 동작하며, 특히 MariaDB 환경에서는 테이블명/칼럼명 대소문자 정책을 정확히 타도록 동작 방식이 변경되었다.

 

운영 DB는 Case-Sensitive 환경이라 Hibernate 가 스키마 검증 과정에서 테이블명을 대소문자 정확히 일치해야 하는 방식으로 비교했고
그 결과 테이블이 존재하지 않는다고 판단하여 missing table 오류가 발생한 것이다.


해결

Dialect를 MariaDB 환경에 맞는 정식 Dialect로 변경했다: org.hibernate.dialect.MariaDB106Dialect

그리고 개발/스테이징/운영의 설정을 DBA를 통해 동일하게 변경하였다.

 

변경 후 다시 스키마 검증 및 전체 테스트를 진행했고 운영 배포에서도 장애 없이 정상 구동을 확인했다.

 

- JPA/Hibernate 에서 Dialect(방언)란? 

사용하는 DB 종류에 맞춰 Hibernate 가 생성하는 SQL 문법을 결정하는 설정이다.
즉, Hibernate 가 직접 SQL 을 생성할 때 다음 요소들을 Dialect 가 결정한다:

  • 테이블/칼럼 이름을 어떻게 인식하고 비교할지
  • 문자열 비교 방식(대소문자 구분 여부 반영 여부)
  • DDL 생성 시 사용하는 문법 (AUTO_INCREMENT, 엔진 타입 등)
  • limit/offset, 대소문자 처리, 조인 전략 등 DB 특화 기능 적용 방식
반응형