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

Spring Data JPA原生查询解析错误:升级Spring Boot 3.2.0后结果异常

Spring Boot 3.2.0升级后原生查询接口投影解析jsonb列异常

问题背景

原技术栈为Spring Boot 3.0.4,使用接口投影结合原生JPA查询,投影接口定义了Optional<Set<String>> getValue();方法,直接映射数据库中jsonb类型的字符串数组列。实体类中该列配置如下:

@Type(io.hypersistence.utils.hibernate.type.json.JsonBinaryType.class)
@Column(name = "value", columnDefinition = "jsonb", nullable = false)
private Set<String> value = new HashSet<>();

升级至Spring Boot 3.2.0后,原生查询返回结果异常:预期解析为["value1", "value2"]格式的Set<String>,实际得到被字符串包裹的数组["[\"value1\", \"value2\"]"]。

原因分析

Spring Boot 3.2.x同步升级了Spring Data JPA与Hibernate版本,原生查询结合接口投影时,自定义类型(如JsonBinaryType)的映射逻辑发生了变化。旧版本中Hibernate会自动对原生查询结果应用类型转换器解析jsonb列,新版本则直接返回数据库存储的原始字符串形式,未触发类型转换流程。

解决方案

方案1:数据库层显式解析jsonb列(PostgreSQL适配)

在原生SQL中调用PostgreSQL的jsonb_array_text函数,直接将jsonb数组解析为字符串数组,投影接口可直接映射为Set<String>:

SELECT id, jsonb_array_text(value) AS value FROM your_table WHERE ...

方案2:改用类投影手动解析

接口投影在复杂类型映射上存在局限,改用类投影并手动处理json解析逻辑:

public class EntityProjection {
    private final Long id;
    private final Optional<Set<String>> value;

    // 构造方法接收数据库返回的json字符串,手动解析为Set<String>
    public EntityProjection(Long id, String valueJson) {
        this.id = id;
        if (valueJson == null) {
            this.value = Optional.empty();
            return;
        }
        try {
            Set<String> values = new ObjectMapper().readValue(
                valueJson,
                new TypeReference<Set<String>>() {}
            );
            this.value = Optional.of(values);
        } catch (JsonProcessingException e) {
            this.value = Optional.empty();
        }
    }

    // Getter方法
    public Long getId() { return id; }
    public Optional<Set<String>> getValue() { return value; }
}

Repository中返回该类投影:

@Query(nativeQuery = true, value = "SELECT id, value FROM your_table WHERE ...")
List<EntityProjection> findProjections();

方案3:强制Hibernate应用自定义类型映射

在配置文件中添加Hibernate参数,确保原生查询结果触发自定义类型解析:

spring.jpa.properties.hibernate.type.preferred_json_type=io.hypersistence.utils.hibernate.type.json.JsonBinaryType

同时确认JsonBinaryType已通过Hibernate的TypeContributor正确注册(若未自动注册,需手动配置类型贡献者)。

内容的提问来源于stack exchange,提问作者Кирилл

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:42:46