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

如何用@JdbcTypeCode将PostgreSQL JSONB列转为Java的MultiValueMap

问题

从PostgreSQL数据库读取JSONB列时,使用@JdbcTypeCode(SqlTypes.JSON)注解实现类型转换,自定义实体类CustomClass字段转换正常,但MultiValueMap<String, String>类型的headers字段报错:

org.springframework.dao.InvalidDataAccessApiUsageException: Could not deserialize string to java type: JsonJavaType(org.springframework.util.MultiValueMap<java.lang.String, java.lang.String>)

实体类代码如下:

@Table(name = "test")
@Data
@AllArgsConstructor @NoArgsConstructor
@Builder
public class TestEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", columnDefinition = "INT")
    private Integer id;
    
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "custom", columnDefinition = "JSONB")
    private CustomClass custom;
    
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "headers", columnDefinition = "JSONB")
    private MultiValueMap<String, String> headers;
}

此前通过实现AttributeConverter接口编写自定义转换器配合@Convert注解可正常转换,但希望通过@JdbcTypeCode或类似注解实现自动转换,无需手动编写转换器。

解决方案

1. 替换为具体的MultiValueMap实现类

MultiValueMap是接口,Hibernate的JSON转换器无法自动推断要实例化的实现类,直接将字段类型改为LinkedMultiValueMap(Spring提供的默认实现)即可:

@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "headers", columnDefinition = "JSONB")
private LinkedMultiValueMap<String, String> headers;

2. 配置Jackson支持MultiValueMap接口

如果不想修改字段类型,需要让Jackson识别MultiValueMap接口,可通过以下两种方式实现:

方式一:注册Spring Jackson模块到全局ObjectMapper

在Spring Boot中配置全局ObjectMapper,注册Spring提供的SpringModule,该模块包含了MultiValueMap的序列化/反序列化逻辑:

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new SpringModule());
        return objectMapper;
    }
}

配置后,原实体类的@JdbcTypeCode(SqlTypes.JSON)注解即可正常工作。

方式二:使用@JsonDeserialize指定实现类

在字段上添加@JsonDeserialize注解,指定MultiValueMap的具体实现类,同时确保Spring Jackson模块已引入(Spring Boot默认已包含):

@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "headers", columnDefinition = "JSONB")
@JsonDeserialize(as = LinkedMultiValueMap.class)
private MultiValueMap<String, String> headers;

3. 自定义Hibernate JsonType

如果需要更精细的控制,可以自定义Hibernate的JsonType,传入带有Spring模块的ObjectMapper:

public class SpringJsonType extends JsonType {
    public SpringJsonType() {
        super(
            JsonJavaType.of(MultiValueMap.class, JsonTypeFactory.instance.constructType(MultiValueMap.class)),
            new ObjectMapper().registerModule(new SpringModule())
        );
    }
}

然后在实体类字段上使用自定义类型:

@Type(SpringJsonType.class)
@Column(name = "headers", columnDefinition = "JSONB")
private MultiValueMap<String, String> headers;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:45:56