SPRING JPA를 사용할때 MySQL의 경우, 데이타 입력시 아래의 DB오류가 나는 경우가 있습니다.

SQL Error: 1366, SQLState: HY000  : incorrect string value
....
...

어플리이케이션도 정삭적으로 구동되고, JPA의 ddl-generation도  문제없이 실행되어  테이블이 정상적으로 생성되었는데,
서비스를 통해 생성된 테이블에 한글을 등록해 보면 위의 에러가 나는 경우가 있습니다. 

 

MySQL의 언어설정이 UTF-8로 되어 있지 않아서 발생하는 문제입니다.

 

윈도우등의 한글 OS에 MySQL을 설치하는 경우에는 자동으로 유니코드(utf-8)이 지원되기 때문에 문제가 없지만,

대부분의 경우 MySQL을 리눅스에 설치하기 때문에 기본언어설정이 필요합니다.

 

MySQL설치후 전역설정을 하지 않았거나, 스키마(데이타베이스) 생성시 명시적으로 charset을 utf-8로 지정하지 않았다면 아마 기본언어는 latin1으로 지정될 겁니다.

 

DB 전역설정이나 스키마(데이타베이스)에서 기본언어설정이 utf-8로 설정되어 있지 않더라도 직접 테이블을 생성할 때는 아래처럼 스크립트에 기본 캐릭터 타입을 명시해서 사용하기 때문에 문제가 되지 않습니다.

create table table1 (
       id bigint not null auto_increment,
       txid varchar(36),
       created_at datetime,
       updated_at datetime,
       ..
       ...,
       primary key (id)
    ) engine=InnoDB DEFAULT CHARSET=uft8;

하지만 캐릭터 설정이 지정되어 있지 않는 경우,
JPA의 DDL Auto Generation(SQL 스크립트 자동생성)을 사용하면 문제가 생깁니다.

JPA의 ddl-auto옵션이 지원하는 속성값은 아래와 같습니다.

 

  • none - 실행하지 않음
  • create-drop - 어플리케이션이 구동되고 Session이 시작될때 drop -> create 이 실행되고, Session이 종료될때 (어플리케이션 종료) drop
  • create - 어플리케이션이 구동되고 Session이 시작될때 drop -> create 이 실행
  • update - 스키마가 변경된 경우에만 실행
  • validate - 변경여부 확인 후 출력, 어플리케이션은 종료

 

JPA를 사용하는 개발환경에서는 보통 최초 배포시에는 ddl-auto 속성을 create, create-drop 중 하나를 사용합니다.

jpa:
  database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
  hibernate:
    naming:
      implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    ddl-auto: create
  properties:
    hibernate:
      show_sql: true
      format_sql: true
  generate-ddl: false
  open-in-view: false

어플리이케이션이 구동될때 마다 JPA가 @Entity 어노테이션이 붙은 모델객체를 읽어들여 ddl을 자동으로 만들고 실행을 하게 됩니다. 

 

그런데 어플리케이션을 구동해서 출력된 ddl문을 로그로 보면 DEFAULT CHARSET=uft8 옵션이
적용되어 있지 않음을 확인할 수 있습니다.

 

결국은 DEFAULT CHARSET옵션이 적용되지 않기 때문에 해당 테이블이 만들어질 Scheme(데이타베이스)나 MySQL의 전역설정을 따라가게 되고,  MySQL 전역 또는 데이타베이스의 기본 언어설정이 되어 있지 않는 경우 한글 등록시 위와 같은 에러가 발생하게 됩니다.

해결방법

  1. 이미 테이블이 만들어진 경우에는 DB에서 직접 테이블 속성을 변경하는 방법밖에 없습니다.
mysql> ALTER TABLE [테이블명] convert to charset utf8;
  1. JPA의 ddl-auto 옵션을 create 또는 create-drop 인 경우는 애플리케이션이 구동될때 마다, 테이블이 새로 만들어지기 때문에
    1번의 방법을 사용하면 안 됩니다. MySQL의 전역설정을 변경해야 합니다.
  2. 환경설정 파일을 열어 아래 내용을 추가해 줍니다.
$ sudo vi /usr/local/mysql/my.cnf

[mysqld]
...
default-character-set=utf8
default-collation=utf8_general_ci

 

​ 혹시 my.cnf가 없다면 mysql 루트폴더에 생성하면 됩니다.
​ 수정을 하고 나서 터미널로 나온다음 mysql을 재시작하면 됩니다.

$ sudo service mysql restart 

 

MySQL엔진을 사용하는 AWS RDS의 경우에는 AWS Management console에서 파라메터 그룹 편집기능을 통해 언어설정이 가능합니다.

 

https://yonguri.tistory.com/63?category=754605

 

빈스톡(Elastic Beanstalk) 설정시 주의해야 할 것들 - 1

빈스톡 설정시 주의해야 할, 또는 시행착오를 겪으면서 터득한 팁이라고 할 만한 것들을 간략히 정리해 본다. java 플랫폼(톰캣플랫폼 아님) 설정시 서버포트 지정 빈스톡의 플랫폼 설정을 java플랫폼 으로 설정한..

yonguri.tistory.com

다시 어플리케이션을 구동하고 데이타를 등록해 보면 한글이 정상적으로 등록되는 것을 확인할 수 있습니다.

참고로,  MySQL의 전역언어설정이 utf-8로 되어 있지 않더라도  데이타베이스 생성시 아래처럼 언어설정을 해주면,

해당 데이타베이스에서 생성되는 테이블은 default charset을 지정하지 않아도 자동으로 해당 데이타베이스의 언어설정을 따라가게 됩니다.

 

가능하면, 데이타베이스 생성시 아래와 같이 언어설정을 꼭 해주고 사용하시기를 권장합니다.

mysql> CREATE DATEBASE [데이타베이스명] CHARACTER SET utf8 COLLATE utf8_general_ci;

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기