리액트 프론트엔드에서 회원가입을 위해 스프링 백엔드로 입력된 데이터를 보내 테이블에 데이터를 추가하는 도중 다음과 같은 에러가 발생했다.
java.sql.SQLException: Incorrect string value: '\xEC\x9C\xA0\xEB\xB3\x91...' for column 'member_name' at row 1
아래를 더 살펴보면 mysql에 관련된 예외가 터진것을 확인할 수 있었다.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1350) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-4.0.3.jar!/:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar!/:na]
에러 메시지를 읽어본 결과 인코딩과 관련된 문제가 발생했을 것이라고 예상했다.
다음 두 쿼리를 실행해서 어떤 방식으로 인코딩 설정이 되어있는지 확인한다.
SELECT default_character_set_name, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA
WHERE schema_name = "fbl";
SELECT CCSA.character_set_name FROM information_schema.`TABLES` T,
information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
WHERE CCSA.collation_name = T.table_collation
역시 UTF-8이 아니었다. 이제 UTF-8로 변경해야한다.
이 해결 방법은 CentOS7 과 mysql 5.7.36 버전 기준이다. MySQL 5.5 이상에서 통하는 해결 방법이다.
1.sudo vim /etc/my.cnf 로 설정 파일 열기
[mysqld] 밑에
collation-server = utf8_unicode_ci
character-set-server = utf8
skip-character-set-client-handshake 추가
sudo systemctl restart mysqld 명령어로 mysql 재시작
이렇게하면 앞으로 만들어지는 db, table은 UTF-8 설정으로 만들어진다.
기존의 테이블은 바뀌지 않기 때문에 모두 삭제하고 다시 만들면 UTF-8로 만들어진다.
기존의 DB 스키마와 테이블에 대한 인코딩 설정을 변경하려면 아래의 쿼리를 사용하면 된다.
ALTER DATABASE <database_name> CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
utf8mb4은 4byte를 표현하는 character set으로 mysql의 utf-8은 3byte 밖에 표현 못하므로 4byte를 사용하는 😆와 같은 이모지를 표현할 때 사용한다. 그 외 다른 DBMS에서는 UTF-8만으로도 4byte를 지원한다고 한다. (MySQL 5.5.3 버전 이상에서 지원한다고 함.)