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

Postgres JSON字段保存报错:column类型为json但表达式为smallint[]

PostgreSQL JSON字段保存时类型不匹配问题排查与解决

问题场景

PostgreSQL数据库中category表有一个data_processing_steps JSON类型字段,实体类定义如下:

@Type(JsonType.class)
@Column(columnDefinition = "json")
private Set<DataProcessingStep> dataProcessingSteps = new HashSet<>();

对应的Flyway迁移脚本:

ALTER TABLE category ADD COLUMN IF NOT EXISTS data_processing_steps json not null default '[]'::json;

保存实体时抛出错误:

[ERROR: column "data_processing_steps" is of type json but expression is of type smallint[]

SQL日志显示参数被识别为数组类型:

DEBUG org.hibernate.SQL[135] - insert into category (active,label,created_by,created_date,data_processing_steps) values (?,?,?,?,?)
2024-07-08 22:11:01.087 [main] TRACE org.hibernate.orm.jdbc.bind[24] - binding parameter (1:BOOLEAN) <- [true]
2024-07-08 22:11:01.087 [main] TRACE org.hibernate.orm.jdbc.bind[24] - binding parameter (2:VARCHAR) <- [label1]
2024-07-08 22:11:01.087 [main] TRACE org.hibernate.orm.jdbc.bind[24] - binding parameter (3:VARCHAR) <- [user@domain.com]
2024-07-08 22:11:01.087 [main] TRACE org.hibernate.orm.jdbc.bind[24] - binding parameter (4:TIMESTAMP_UTC) <- [2024-07-08T22:11:01.087618+03:00]
2024-07-08 22:11:01.088 [main] TRACE org.hibernate.orm.jdbc.bind[24] - binding parameter (5:ARRAY) <- [[]]

错误原因

Hibernate默认会把Set类型集合映射为PostgreSQL的SQL数组类型(此处表现为smallint[]),但数据库字段定义为json类型,两者类型不匹配,导致插入操作时抛出类型错误。从日志可见,Hibernate将dataProcessingSteps参数识别为ARRAY而非JSON。

解决方法

1. 正确配置Hibernate Types注解(适用于Hibernate 5.x)

若使用com.vladmihalcea:hibernate-types库处理JSON类型,需确保注解配置完整,同时引入对应版本的依赖:

实体类配置:

import com.vladmihalcea.hibernate.type.json.JsonType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import org.hibernate.annotations.Type;

@Entity
public class Category {
    // 其他字段省略
    
    @Type(JsonType.class)
    @Column(columnDefinition = "json NOT NULL DEFAULT '[]'::json")
    private Set<DataProcessingStep> dataProcessingSteps = new HashSet<>();
    
    // getter、setter方法
}

Maven依赖示例(根据Hibernate版本选择对应artifactId):

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-55</artifactId>
    <version>2.20.0</version>
</dependency>

2. 使用Hibernate 6+原生JSON映射

Hibernate 6及以上版本无需额外依赖,可直接用@JdbcTypeCode指定JSON类型:

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Entity
public class Category {
    // 其他字段省略
    
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(columnDefinition = "json NOT NULL DEFAULT '[]'::json")
    private Set<DataProcessingStep> dataProcessingSteps = new HashSet<>();
    
    // getter、setter方法
}

3. 验证数据库字段定义一致性

检查Flyway迁移脚本执行结果,确认category表的data_processing_steps字段确实为json类型,未被误修改为数组类型。

内容的提问来源于stack exchange,提问作者Lesha Pipiev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:35:55