Spring Boot3升级后使用GenerationType.UUID报JDBC SQLException问题排查
问题原因
Spring Boot 3 默认使用 Hibernate 6,它对 UUID 的默认映射行为和 Spring Boot 2 所用的 Hibernate 5 存在差异:
- 在 Hibernate 5 中,你通过
@Type(type = "uuid-char")显式指定将 UUID 转换为 36 位字符串格式存储,完全匹配 MySQL 的varchar(36)列类型。 - 升级到 Hibernate 6 后,当使用
GenerationType.UUID生成 UUID 时,Hibernate 默认会将 UUID 以二进制字节数组的形式处理,而你的数据库列是字符串类型,直接写入二进制数据会产生无效的 UTF-8 字符,从而触发Incorrect string value错误。
解决方案
有两种方式可以解决该问题,任选其一即可:
1. 针对单个实体字段配置映射类型
在 UUID 字段上显式指定使用字符串类型映射,推荐使用 Hibernate 6 新增的 @JdbcTypeCode 注解(贴合 Jakarta 规范):
import jakarta.persistence.Id; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; import java.util.UUID; @Id @GeneratedValue(strategy = GenerationType.UUID) @JdbcTypeCode(SqlTypes.CHAR) private UUID id;
或者继续使用兼容的 @Type 注解(Hibernate 6 仍支持):
import jakarta.persistence.Id; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import org.hibernate.annotations.Type; import java.util.UUID; @Id @GeneratedValue(strategy = GenerationType.UUID) @Type(type = "uuid-char") private UUID id;
2. 全局配置默认 UUID 映射类型
如果不想逐个实体修改,可以在 Spring Boot 配置文件中添加全局设置,让所有 UUID 字段默认以字符串格式存储:
application.properties
spring.jpa.properties.hibernate.type.preferred_uuid_jdbc_type=CHAR
application.yml
spring: jpa: properties: hibernate: type: preferred_uuid_jdbc_type: CHAR
验证
配置完成后重启应用,插入数据时 UUID 会被正确转换为 xxxx-xxxx-xxxx-xxxx 格式的字符串,存入 MySQL 的 varchar(36) 列,不会再触发编码错误。
内容的提问来源于stack exchange,提问作者Julez
相关产品推荐
相关产品推荐

