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

Spring Data JPA原生查询返回DTO遇转换器异常,寻求Class-Based Projections修复方案

解决Spring Data JPA原生SQL查询映射Class-Based Projection的问题

方案1:通过@SqlResultSetMapping+@ConstructorResult显式映射

在实体类SigningKeysEnt上添加结果集映射规则,指定用SigningKey的构造函数来转换查询结果:

@Entity
@Table(name = "signing_keys")
@Getter
@Setter
@SqlResultSetMapping(
    name = "SigningKeyProjection",
    classes = @ConstructorResult(
        targetClass = SigningKey.class,
        columns = {
            @ColumnResult(name = "public_key", type = String.class),
            @ColumnResult(name = "protocol_version", type = String.class),
            @ColumnResult(name = "expiration_date", type = Date.class)
        }
    )
)
public class SigningKeysEnt {
    // 原有字段逻辑保持不变
}

接着修改Repository的查询注解,指定使用上述映射规则:

@Repository
public interface SigningKeysRepository extends JpaRepository<SigningKeysEnt, Long> {

  @Query(value = """
                    SELECT public_key,
                           protocol_version,
                           expiration_date
                    FROM signing_keys                                               
            """, 
         nativeQuery = true,
         resultSetMapping = "SigningKeyProjection")
  List<SigningKey> getPublicKeys();
}

注意:SQL中无需给字段加别名,@ColumnResult直接对应数据库表字段名,且列的顺序必须和SigningKey构造函数的参数顺序完全一致。

方案2:通过编译参数+别名匹配构造函数参数

如果不想添加映射注解,可通过以下两步实现自动映射:

  1. 确保编译时保留构造函数参数名(Maven配置示例):
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source> <!-- 匹配你的项目JDK版本 -->
                <target>1.8</target>
                <compilerArgs>
                    <arg>-parameters</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>
  1. 修改SQL查询的别名,使其与SigningKey构造函数的参数名完全匹配:
@Query(value = """
                    SELECT public_key AS publicKey,
                           protocol_version AS protocolVersion,
                           expiration_date AS expirationDate
                    FROM signing_keys                                               
            """, nativeQuery = true)
List<SigningKey> getPublicKeys();

问题根源说明

原生SQL查询默认返回TupleBackedMap类型,Spring Data JPA不会自动将其转换为自定义DTO——即使添加了构造函数,也需要通过显式映射或参数名匹配的方式,明确告诉JPA如何将查询结果转换为目标DTO实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:20:06