일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- mysql not equal null
- load order
- 1*1000
- Protecle
- mysql equal null
- https
- sendFractionalSeconds
- jdbc characterencoding utf8mb4
- 오블완
- apatch poi
- spring boot
- getEntityGraph
- 운영체제별 차이
- createEntityGraph
- 티스토리챌린지
- 운동해서 광명찾자
- RootGraph
- AuditingEntityListener
- getDateCellValue
- yml
- MSSQL
- fractional seconds
- mysql =
- +9:00
- 버전 문자열 비교
- NamedEntityGraph
- jdbc utf8mb4
- java jdbc utf8mb4 연결 오류
- MYSQL
- mysql8업그레이드
- Today
- Total
Hello
MySQL 5에서 8로 업그레이드 시 utf8mb4와 JDBC characterEncoding 옵션 설정 본문
MySQL 5.x 버전의 지원 종료로 8버전으로 업그레이드를 진행하게 되었습니다.
기존에 JDBC characterEncoding 옵션을 utf8로 사용하고 있었으나, 관련 문서에서 utf8mb4를 사용해야 한다는 내용을 확인하고, 이를 변경한 후 발생한 에러를 해결하기 위한 과정에서 characterEncoding 옵션과 관련한 내용을 정리합니다.
1. JDBC 연결 문자열 옵션 변경 (utf8 → utf8mb4)
기존 : ?useUnicode=true&characterEncoding=utf8
변경 : ?useUnicode=true&characterEncoding=utf8mb4
2. 런타임 에러 발생
utf8mb4를 지원하지 않는다는 에러 발생
Caused by: com.mysql.cj.exceptions.WrongArgumentException: Unsupported character encoding 'utf8mb4'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_242]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_242]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_242]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_242]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.27.jar:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.27.jar:8.0.27]
at com.mysql.cj.util.StringUtils.getBytes(StringUtils.java:231) ~[mysql-connector-java-8.0.27.jar:8.0.27]
at com.mysql.cj.jdbc.JdbcPropertySetImpl.postInitialization(JdbcPropertySetImpl.java:66) ~[mysql-connector-java-8.0.27.jar:8.0.27]
at com.mysql.cj.conf.DefaultPropertySet.initializeProperties(DefaultPropertySet.java:231) ~[mysql-connector-java-8.0.27.jar:8.0.27]
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:390) ~[mysql-connector-java-8.0.27.jar:8.0.27]
... 126 common frames omitted
Caused by: java.io.UnsupportedEncodingException: utf8mb4
at java.lang.StringCoding.encode(StringCoding.java:341) ~[na:1.8.0_242]
at java.lang.String.getBytes(String.java:918) ~[na:1.8.0_242]
at com.mysql.cj.util.StringUtils.getBytes(StringUtils.java:229) ~[mysql-connector-java-8.0.27.jar:8.0.27]
... 129 common frames omitted
3. 디버깅 및 원인 분석
디버깅을 통해 JdbcPropertySetImpl.postInitialization 메소드에서 발생한 문제의 원인을 확인했습니다. 해당 메소드의 에러는 utf8mb4 인코딩을 처리하려 할 때, Java에서 utf8mb4 인코딩을 지원하지 않아 UnsupportedEncodingException이 발생했으며, 이로 인해 JDBC 연결 문자열 설정 오류가 있음을 확인했습니다.
JdbcPropertySetImpl.postInitialization 일부
String testEncoding = getStringProperty(PropertyKey.characterEncoding).getValue();
if (testEncoding != null) {
// Attempt to use the encoding, and bail out if it can't be used
String testString = "abc";
StringUtils.getBytes(testString, testEncoding);
}
StringUtils.getBytes()에서 testEncoding 값으로 "utf8mb4"가 전달되면서, String.getBytes("utf8mb4") 호출 시 에러가 발생했습니다. 이 문제는 Java에서 utf8mb4 인코딩을 지원하지 않기 때문에 발생했습니다.
따라서, characterEncoding=utf8mb4 설정은 지원되지 않으며, 호환성 문제가 발생할 수 있습니다. 이 문제를 해결하려면 characterEncoding을 UTF-8로 설정해야 합니다.
4. 해결 방법: UTF-8 사용
characterEncoding을 UTF-8로 설정해도 문제가 없는 이유는, utf8과 utf8mb4가 서로 호환되기 때문입니다. UTF-8 인코딩을 사용하면, MySQL 서버에서 utf8mb4를 사용할 때도 데이터가 호환성 문제 없이 정상적으로 처리됩니다.
- characterEncoding은 Java 애플리케이션에서 MySQL 서버로 데이터를 전송하거나, MySQL 서버에서 Java 애플리케이션으로 데이터를 읽을 때 사용할 문자 인코딩을 정의합니다.
- Java 클라이언트 측에서는 UTF-8을 사용하고, MySQL 서버 측에서는 utf8mb4를 사용하게 되며, 이 두 인코딩은 실질적으로 동일한 방식으로 데이터를 처리합니다.
- 이유는 utf8mb4가 UTF-8의 확장판으로, 기본적으로 UTF-8을 기반으로 하여 최대 4바이트 문자까지 처리할 수 있도록 설계되었기 때문입니다. UTF-8은 1~4바이트를 사용하여 데이터를 저장하고, MySQL의 utf8mb4는 4바이트를 지원해 더 넓은 범위의 문자를 처리할 수 있습니다., 두 인코딩은 대부분의 경우 동일하게 작동하며 UTF-8을 사용하는 Java 클라이언트와 utf8mb4를 사용하는 MySQL 서버 간에 데이터가 호환성 문제 없이 주고받을 수 있습니다.
결론
utf8mb4는 MySQL에서만 사용하는 문자셋이기 때문에, Java에서 이를 직접 사용할 수 없습니다. 대신 UTF-8을 사용하여 호환성 문제 없이 MySQL의 utf8mb4와 데이터를 주고받을 수 있습니다.
+) character_set_server=utf8mb4 옵션은 db 서버의 character을 설정하는 옵션이다. 디비가 이미 utf8mb4로 설정 되어있다면 이 옵션은 추가적인 영향을 미치지 않는다.
'java' 카테고리의 다른 글
[Stream] 그룹핑 후 정렬 처리 (0) | 2025.02.07 |
---|---|
[Hibernate] Inheritance Mapping (0) | 2024.11.07 |
[Querydsl] Subquery 및 Result handling (0) | 2024.07.31 |
[JAVA] instanceof null 검사? (0) | 2024.04.29 |
local에서 keytool or portecle 사용해 인증서 생성 및 ssl 적용 (0) | 2024.02.01 |