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

Spring Boot JPA原生查询JSONB自动映射DTO的实现方法

问题描述

依赖配置:

springBootVersion = '3.4.5'
org.springframework.boot:spring-boot-starter-data-jpa
io.hypersistence:hypersistence-utils-hibernate-63:3.9.0

实体类中通过以下配置实现jsonb列到List<SomeDtoClass>的自动转换:

@Entity
class TestEntity {
    // ...
    @Type(JsonBinaryType.class)
    @Column(columnDefinition = "jsonb")
    List<SomeDtoClass> test;
}

但使用原生SQL查询返回自定义DTO时,无法自动转换jsonb字段,报错Cannot cast java.lang.String to java.util.List:

@Repository
interface Repo extends JpaRepository<TestEntity, UUID> {
  @Query(
    """
    SELECT 
      CAST(test AS jsonb) AS test,
      'example' AS example
    FROM test
    """,
    nativeQuery = true
  )
  List<Dto> find();
}

目标DTO定义:

@Data
@NoArgsConstructor
@AllArgsConstructor
class Dto {
  List<SomeDtoClass> test;
  String example;
}

需要实现DTO字段的自动类型转换,复用实体类中的转换逻辑,且不新增额外依赖。

解决方案

方法一:使用@SqlResultSetMapping指定类型映射

  1. 定义结果集映射,为test列指定JsonBinaryType类型转换器:
@SqlResultSetMapping(
    name = "DtoMapping",
    classes = @ConstructorResult(
        targetClass = Dto.class,
        columns = {
            @ColumnResult(name = "test", type = JsonBinaryType.class),
            @ColumnResult(name = "example", type = String.class)
        }
    )
)
// 可将此注解添加到TestEntity类上,或单独创建一个空的实体类承载映射配置
@Entity
class DummyMappingHolder {}
  1. 在原生查询中引用该结果集映射:
@Repository
interface Repo extends JpaRepository<TestEntity, UUID> {
  @Query(
    value = """
    SELECT 
      test AS test,
      'example' AS example
    FROM test
    """,
    nativeQuery = true,
    resultSetMapping = "DtoMapping"
  )
  List<Dto> find();
}

方法二:在DTO字段上添加@Type注解

直接在DTO的test字段上添加实体类中相同的@Type注解:

@Data
@NoArgsConstructor
@AllArgsConstructor
class Dto {
  @Type(JsonBinaryType.class)
  List<SomeDtoClass> test;

  String example;
}

同时确保DTO所在包被Hibernate扫描到,可在application.properties中添加配置:

spring.jpa.properties.hibernate.archive.autodetection=class, hbm

说明

  • 方法一更可靠,原生查询的结果集映射明确指定了类型转换规则,不受DTO扫描范围影响。
  • 两种方法均复用已有的JsonBinaryType转换器,无需新增依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:43:20