Mysql Incorrect string value

今天遇到了一个比较坑的问题,记录一下。

最初是数据在更新时报了这个错误:Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1,第一时间以为是表字段的字符编码不对,满怀信心的将字段的编码类型改为 utf8mb4 后发现还是报同样的错。

java 复制代码
exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: 
### Error updating database.  Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1
### The error may exist in com/example/platform/dao/mysql/mapper/UmsPrintSystemVersionDaoMapper.java (best guess)
### The error may involve com.example.platform.dao.mysql.mapper.UmsPrintSystemVersionDaoMapper.updateById-Inline
### The error occurred while setting parameters
### SQL: UPDATE tb_ums_print_system_version  SET description=?,         update_time=?  WHERE id=?
### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1
; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1; nested exception is java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1] with root cause
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\xF0\x9F...' for column 'description' at row 1
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2486)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
	......

于是将这个错误消息贴到了 AI 上,得到的回复是修改连接字符串:

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8mb4&collation=utf8mb4_unicode_ci

对比下使用的连接字符串参数,当前使用的是 characterEncoding=utf8,于是修改为 characterEncoding=utf8mb4。但修改之后客户端启动不起来了,数据库连接失败。

之后各种测试后发现:

  • 该服务在测试环境是好的;
  • 生产环境的另一个使用该数据库的服务也是可以保存 4 字节的特殊符号的。

对比了下测试环境和生产环境的版本和默认字符集。

sql 复制代码
SELECT VERSION();
-- 测试环境:5.7.30
-- 生产环境:5.7.18
SHOW VARIABLES LIKE 'character_set_server';
-- 测试环境:utf8mb4
-- 生产环境:utf8

测试环境正常猜测是因为其默认字符集是 utf8mb4(后面找到的文章里也可以证实就是该配置影响的)。生产环境如果修改 character_set_server 配置需要重启数据库服务,这就有点麻烦了,一般生产环境如果需要重启,大都设置在凌晨三四点钟(这个时间段访问用户最少)。虽然可以设置定时重启,但实在不想早起确认服务是否正常,于是继续调查是否还有别的解决方案,毕竟还有别的服务是可以正常保存的。

首先是对比下这两个服务使用的连接字符串,都是使用的 useUnicode=true&characterEncoding=utf-8。

之后比较了 MySQL connector 的版本,发现确实有区别:正常的那个服务使用的是 5.1.47 ,有问题的服务使用的是 5.1.46。

xml 复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

本来没期望修改了小版本号可以解决这个问题,但测试下来确实是可以了。最后还是通过百度搜到了具体的原因 ^1^:

Connector/J 5.1.47 及以上版本:

指定 characterEncoding 参数为 UTF8/UTF-8 即可, 新版本直接映射到 utf8mb4 编码; 如果 connectionCollation 指定的排序规则不是 utf8mb4 相关的, 则 characterEncoding 参数会重写为排序规则对应的编码;

Connector/J 5.1.47 以下版本:

设置 MySQL 参数变量 character_set_server=utf8mb4; 指定 characterEncoding 参数为 UTF8/UTF-8, jdbc 程序会进行探测是否使用 utf8mb4;

上面的说明和之前自己的测试结果都是吻合的。

Footnotes

  1. mysql 字符集引起的 java.sql.SQLException: Incorrect string value: ↩
相关推荐
桃西西呀20 分钟前
Spring AI Alibaba 之二:Spring AI 底座与原子抽象一笔带过,看清 SAA 在之上加了什么编排
人工智能·spring·llm
写后端的胖头鱼1 小时前
一文详解Spring 事务失效场景
java·spring·事务·transactional·事务传播机制
Q26433650231 小时前
【有源码】基于Spring Boot和Vue的在线考试与交流系统-教育信息化背景下在线考试与交流一体化平台
java·vue.js·spring boot·mysql·spring·毕业设计·课程设计
会编程的吕洞宾2 小时前
Spring AI 2.0 会话记忆实战,让 AI 助手记住每一次对话
java·人工智能·spring
小宋10212 小时前
Agent 工具升级如何不破坏线上:Tool Schema 版本兼容与契约测试
java·人工智能·后端·spring
都适、隶仁ミ2 小时前
【等保加固】MySQL5.7.38
运维·服务器·mysql·安全·等保
EatFan2 小时前
2026 后端 AI 集成三条落地路径:Spring AI 2.0、MCP 协议与旁路服务怎么选
java·人工智能·spring boot·spring·大模型·spring ai·mcp
桃西西呀2 小时前
Spring AI Alibaba 之一:整体概览与分层架构,看清它在 Spring AI 之上到底加了什么
人工智能·spring·llm
fengkai45453 小时前
十一、MySQL 第 4-7 章
运维·数据库·mysql
学编程就要猛3 小时前
Spring AI Alibaba(上)
java·人工智能·spring·springaialibaba