[Spring boot] JPA Dialect(방언) 설정에 관하여

이동빈·2021년 8월 23일
4

결론만 말씀드리면 "Dialect 설정은 하지 않는걸 추천드립니다." 입니다.

1. Dialect 란?

ORM의 큰 특징중 하나는 객체 맵핑을 통해 자동으로 쿼리를 작성해주는 것입니다. 하지만 수 많은 DBMS 종류가 있고 각 종류마다 쿼리가 조금씩 다르기 때문에, 이를 알릴 수 있도록 데이터베이스 유형을 지정하도록 하는 것이 Dialect 설정 입니다.

이런 Dialect 설정은 연결되는 Springboot 실행 시, 연결되어있는 데이터베이스에 알맞게 자동으로 지정이 되므로, 특별한 이유가 존재하지 않는 이상 수동으로 설정할 필요가 없습니다.

여러가지 데이터베이스를 하나씩 연결하여 확인해보면 아래 로그와 같이 연결되는 DB에 알맞게 Dialect 설정이 되는 것을 확인할 수 있습니다.

저 처럼 인터넷에 떠돌아다니는 JPA properties 값을 복사/붙여넣기 하여,

잘 모르는 상태에서 spring.jpa.properties.hibernate.dialect 설정값을 그대로 가져다가 쓰시는 분이 계시다면 해당 부분은 지우시는걸 권장드립니다.

그렇지 않으면 현재 사용하는 데이터베이스와 다르게 Dialect가 설정되어 큰 고생을 하게 됩니다.

2. 무엇이 문제가 되는가?

물론 오라클 DB를 사용하는데, MySQL Dialect로 설정하거나, MySQL DB를 사용하는데 오라클 Dialect로 설정하신 분들은 없으실 겁니다.

다만, MySQL과 MariaDB가 서로 호환되는 사실에, 둘이 혼용하거나 버전에 맞지않은 Dialect 설정을 하는 것이 문제 됩니다.

저의 경우, MariaDB 10.4 버전을 사용하는데, Dialect 설정값 MySQL5Dialect을 사용했습니다.
(MySQL5Dialect 은 MysQL 5.5 이전 버전을 뜻합니다.)

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

이런식으로 말이죠..

이미 MySQL 버전의 차이에 대해 잘 알고계신 분들은 눈치 채셨을겁니다.

저렇게 설정을 한다고해서 에러가 발생하다거나 JPA가 동작을 안하지는 않습니다. 다만 Hibernate에서 SQL 쿼리로 변환하는 과정에서 MySQL 5.x 버전(5.5이전) 기준으로 변환 될 뿐이죠.

저 같은 경우, 이렇게 설정을 하면서 2가지 문제를 겪었습니다.

2-1 트랜잭션 동작 안함

MySQL 5.5 이전버전의 기본 스토리지 엔진은 InnoDB가 아닌 MyISAM 입니다.

MySQL 5.5부터 기본 스토리지 엔진이 InnoDB로 채택됩니다.

두 스토리지 엔진의 가장 큰 차이점은 트랙잭션 기능 유무입니다.

Dialect를 MySQL5Dialect으로 설정했던 탓에 MyISAM 엔진이 기본으로 선택되어 트랜잭션이 동작하지 않았습니다.

테이블이 생성 될 때 쿼리를 확인해보면 MyISAM으로 생성되는 것을 확인할 수 있습니다.

MySQL5Dialect의 부모클래스인 MySQLDialect 클래스 생성자의 소스코드를 살펴보면 해당 내용이 있습니다.

스토리지 엔진을 별도로 지정하지 않으면 getDefaultMySQLStorageEngine 메소드를 호출하는데,

기본 스토리지 엔진이 MyISAM으로 되어있는것을 확인할 수 있습니다.

추가적으로, MySQL 5.5 버전 타겟인 MySQL55Dialect를 살펴보면,

MySQL5Dialect 클래스를 상속받아 getDefaultMySQLStorageEngine() 메소드가 InnoDB로 재정의 되어있는 것을 볼 수 있습니다.

2-2 datetime 밀리세컨드 단위 저장 안됨

저의 경우, 데이터베이스는 당연히 최신이니 직접 쿼리를 할 땐 밀리세컨드까지 저장이 잘 되었으나,

JPA를 통해 저장이 될 때는 밀리센컨드 단위가 잘려서 저장되었습니다.

datetime 타입에서 밀리세컨드를 정식으로 지원하는 MySQL 버전은 5.6.4 입니다. (MariaDB는 5.3 부터 지원)

MySQL 최신버전을 사용하는데 밀리세컨드 저장이 안된다면 Dialect 설정을 확인하면 됩니다.

(밀리세컨드를 지원하는 Dialect는 MySQL57Dialect 이상입니다)

MySQL57Dialect 클래스의 소스코드를 확인해보면 관련 내용에 대해 상세한 설명이 되어있는 것을 볼 수 있습니다.

MariaDB를 사용하는데 밀리세컨드 저장이 안된다면 커넥터를 MriaDB 커넥터로 바꾸시길 바랍니다.

3. Dialect 클래스 정리

Hibernate 5.4 기준으로 작성한 MySQL & MariaDB Dialect 클래스 구조입니다.

새로운 DB 버전이 릴리즈 될 때, 하위버전 Dialect 클래스를 상속받아 추가된 기능을 재정의 하는 방식으로 Dialect 클래스가 추가되고 있습니다. 디자인패턴을 배우고나니 프레임워크의 구조를 뜯어보게 되네요.

4. Deprecated Dialect 설정 값

JPA Properties 관련해서 구글링 하다보면 간혹 예제로 Deprecated 된 설정값으로 되어있는 경우가 있습니다.

  • MySQL57InnoDBDialect
  • MySQL5InnoDBDialect
  • MySQLInnoDBDialect

등등.. 이 존재하는데, 자세한건 Hibernate 공식문서에서 확인할 수 있습니다.

잘 모르고 설정했다가는 문제가 발생할 수 있으니, 수동으로 설정을 하게 된다면 잘 알고 하는게 좋고
그렇지 않으면 따로 Dialect 설정을 할 필요가 없겠습니다.

profile
호기심 많은 개발자

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

덕분에 좋은 내용 잘 보고 갑니다.
정말 감사합니다.

답글 달기