You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot2+JPA+Hibernate+PostgreSQL保存实体时UTF-8异常

解决PostgreSQL中UTF-8编码的0x00字节序列错误(Spring Boot + JPA场景)

问题背景

你在使用Spring Boot 2搭配JPA、Hibernate和PostgreSQL开发时,遇到了数据插入阶段的UTF-8编码异常,日志明确提示ERROR: invalid byte sequence for encoding "UTF8": 0x00,这是PostgreSQL中非常典型的空字节编码冲突问题。

先梳理下你的环境配置和错误日志:

Gradle编译配置

tasks.withType(JavaCompile) {
    options.compilerArgs = ["-Xlint:unchecked", "-Xlint:deprecation", "-parameters"]
    options.encoding = "UTF-8"
}

核心错误日志片段

select nextval ('ignar.hibernate_sequence')
Hibernate: select nextval ('ignar.samples_id_seq')
Hibernate: insert into ignar.samplings (available_for_test, build_date, color_id, dimension_id, machine_id, print, product_id, reception_date, remark, special_try, test_done, to_print, delay_before_doing_test, press, quantity_received, dtype, id, year) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'TraditionalSamplings', ?, ?)
Hibernate: insert into ignar.samples (created_at, updated_at, absorption_printed, aen_remarque, certificat_include, cube, durability_printed, fresh_density, fresh_weigth, gen_remarque, label, position, sample_letter, sampling_id, sampling_year, absorption, absorption_number, coloration, coloration_number, compression, compression_number, density, draw_down, draw_down_number, durability, durability_number, granulometry, granulometry_number, organic_material, organic_material_number, scaling, scaling_number, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2018-05-21 15:38:21.214 WARN 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 22021
2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: invalid byte sequence for encoding "UTF8": 0x00
2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.DataException: could not execute statement]

问题根源

PostgreSQL的UTF-8编码规则严格禁止字符串中包含空字节(0x00),而你的实体类中某个字符串字段(比如remark、gen_remarque这类备注型字段)被传入了带有空字节的内容,Hibernate执行插入操作时触发了数据库的编码校验异常。

解决步骤

1. 定位带空字节的问题字段

首先要找出到底是哪个字段携带了空字节。你可以在保存实体对象前,添加一段检查代码,或者通过调试断点查看实体属性的具体内容:

// 工具方法:检查字符串是否包含空字节
private boolean hasNullByte(String str) {
    return str != null && str.indexOf('\0') != -1;
}

// 在保存前逐个字段排查
if (hasNullByte(entity.getRemark())) {
    System.out.println("remark字段包含空字节");
}
if (hasNullByte(entity.getGenRemarque())) {
    System.out.println("gen_remarque字段包含空字节");
}
// 以此类推检查所有字符串类型字段

2. 清理空字节内容

找到问题字段后,需要在数据入库前将空字节清理掉,有两种常用处理方式:

  • 业务层单独处理:如果只有个别字段出现问题,直接在设置属性时替换空字节:
    // 将空字节替换为空字符串
    entity.setRemark(remark == null ? null : remark.replace("\0", ""));
    
  • 全局统一处理(推荐):如果多个字段都可能出现这个问题,使用JPA的AttributeConverter做全局转换,自动清理所有字符串字段的空字节:
    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter(autoApply = true) // 自动应用到所有字符串字段
    public class StringNullByteCleaner implements AttributeConverter<String, String> {
        @Override
        public String convertToDatabaseColumn(String attribute) {
            if (attribute == null) {
                return null;
            }
            // 移除所有空字节
            return attribute.replace("\0", "");
        }
    
        @Override
        public String convertToEntityAttribute(String dbData) {
            return dbData;
        }
    }
    
    这个转换器会自动生效,无需在每个字段上单独标注配置。

3. 确认数据源连接编码

确保你的Spring Boot数据源配置明确指定了UTF-8编码,避免连接层面的编码不一致:

application.properties配置

spring.datasource.url=jdbc:postgresql://localhost:5432/your_db?useUnicode=true&characterEncoding=UTF-8
spring.datasource.hikari.connection-init-sql=SET NAMES 'UTF8'

application.yml配置

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/your_db?useUnicode=true&characterEncoding=UTF-8
    hikari:
      connection-init-sql: SET NAMES 'UTF8'

4. 验证数据库表字段编码

最后确认数据库中相关表的字段编码为UTF-8,执行以下SQL查询:

SELECT column_name, data_type, character_set_name 
FROM information_schema.columns 
WHERE table_name IN ('samples', 'samplings') AND table_schema = 'ignar';

如果发现字段编码不是UTF-8,执行ALTER语句修改:

ALTER TABLE ignar.samples ALTER COLUMN gen_remarque TYPE VARCHAR(255) CHARACTER SET UTF8;

内容的提问来源于stack exchange,提问作者robert trudel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:03:57