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

Spring Boot中JPA/Hibernate存JSON报错:原生SQL正常却提示字段过长

问题分析:JPA持久化JSON字段时报数据过长错误,原生SQL却正常

我正在开发基于Spring Boot的应用,使用JPA和Hibernate框架,尝试通过自定义@Converter将字段序列化为JSON后,持久化到MySQL的varchar(2000)列中。

DTO

@XmlElement
private Object value;

实体类

@Column(name = "value")
@Convert(converter = JpaConverterJson.class)
private Object value;

转换器

@Component
@Converter
@Slf4j
public class JpaConverterJson implements AttributeConverter<Object, String> {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public String convertToDatabaseColumn(Object meta) {
        try {
            objectMapper.disable(SerializationFeature.WRAP_ROOT_VALUE);
            return objectMapper.writeValueAsString(meta);
        } catch (JsonProcessingException ex) {
            log.error("JsonProcessingException encoding Object into String: {}", ex.getMessage());
            return null;
        }
    }

    @Override
    public Object convertToEntityAttribute(String dbData) {
        try {
            return objectMapper.readValue(dbData, Object.class);
        } catch (IOException ex) {
            log.error("IOException decoding json from database: {}", ex.getMessage());
            return null;
        }
    }
}

问题

执行原生SQL INSERT语句时,数据可正常存储;但通过JPA持久化实体时,出现如下错误:

com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'value' at row 1

为何原生SQL能正常存储,而Hibernate却无法持久化数据?


原因分析

  • Hibernate预校验逻辑限制
    实体类中value字段为Object类型,且@Column未显式指定length属性,Hibernate会默认将其映射为长度255的字符串类型。在持久化时,Hibernate会先校验数据长度是否符合这个默认限制,即便转换器序列化后的JSON字符串长度在MySQL列的2000限制内,也会因Hibernate的预校验触发错误。而原生SQL直接操作数据库,不会经过这层校验,只要数据长度不超过列定义就能存储。

  • MySQL模式差异
    若MySQL未开启严格模式(如STRICT_TRANS_TABLES),原生SQL插入过长数据时会自动截断并完成插入;但Hibernate默认严格遵循校验规则,直接抛出异常,不会自动截断数据。

解决方法

  1. 显式指定字段长度
    修改实体类的@Column注解,将length设置为与数据库列一致的2000:

    @Column(name = "value", length = 2000)
    @Convert(converter = JpaConverterJson.class)
    private Object value;
    

    这样Hibernate会按照指定长度校验数据,只要序列化后的JSON字符串长度不超过2000,就能正常持久化。

  2. 开启MySQL严格模式(可选)
    若想避免MySQL自动截断数据的隐式行为,可开启STRICT_TRANS_TABLES模式,这样原生SQL插入过长数据时也会报错,便于提前发现数据长度问题。


内容的提问来源于stack exchange,提问作者Ibrahim Alvi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:52:09