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

创建TypedQuery报错:配置正确DTO仍提示查询多返回值无法映射

报错排查方案:Cannot create TypedQuery for query with more than one return using requested result type

以下是逐一可落地的修复步骤:

  • 先修复类名拼写错误:你定义的DTO类名为AllRecordsDTO,但createQuery方法中传入的类是AllRecordssDTO,多了1个字母s,先修正该拼写问题。
  • 匹配查询类型与调用方法:createQuery方法仅接收JPQL/HQL语句,你当前编写的是原生SQL语法,若要执行原生SQL需要替换为createNativeQuery方法。
  • 配置查询结果到DTO的映射规则:Hibernate默认不会自动将查询返回的字段映射到自定义DTO类,可任选以下一种方案配置映射:
    1. 方案1:JPQL构造器表达式(无额外注解依赖,推荐)
      将查询改写为JPQL语法,在select后直接调用DTO的全参构造方法,注意字段顺序需和DTO全参构造的参数顺序完全一致,示例语法如下:
    String jpql = "select new com.yourpackage.AllRecordsDTO(" +
                  "r.recordName, " +
                  "rt.recordTypeName, " +
                  "s.name, " +
                  "usi.userId, " +
                  "r.createdDateTime, " +
                  "usi1.userId, " +
                  "r.lastChangedDateTime" +
                  ") from Record r " +
                  "left join r.status s " +
                  "left join r.createdByUser usi " +
                  "left join r.recordType rt " +
                  "left join r.lastChangedByUser usi1";
    Query<AllRecordsDTO> createdQuery = statelessSession.createQuery(jpql, AllRecordsDTO.class);
    
    注:上述JPQL中的关联属性需要和你Record实体中定义的关联字段名保持一致。
    2. 方案2:原生SQL + @SqlResultSetMapping 注解
    在AllRecordsDTO类上添加结果集映射注解,配置字段与DTO属性的对应关系:
    @SqlResultSetMapping(
        name = "AllRecordsDTOMapping",
        classes = @ConstructorResult(
            targetClass = AllRecordsDTO.class,
            columns = {
                @ColumnResult(name = "recordName", type = String.class),
                @ColumnResult(name = "recordTypeName", type = String.class),
                @ColumnResult(name = "statusName", type = String.class),
                @ColumnResult(name = "createdByUserId", type = String.class),
                @ColumnResult(name = "createdDateTime", type = String.class),
                @ColumnResult(name = "lastChangedByUserId", type = String.class),
                @ColumnResult(name = "lastChangedDateTime", type = String.class)
            }
        )
    )
    public class AllRecordsDTO {
        // 原有类代码不变
    }
    
    同时给原生SQL的所有字段添加与上述配置一致的别名:
    select r.recordName as recordName,
           rt.recordTypeName as recordTypeName,
           s.name as statusName,
           usi.userId as createdByUserId,
           r.createdDateTime as createdDateTime,
           usi1.userId as lastChangedByUserId,
           r.lastChangedDateTime as lastChangedDateTime
    from Record r
             left join Section s on s.id = r.statusId
             left join UniqueSecurityIdentifier usi on usi.id = r.createdByUserId
             left join RecordType rt on rt.id = r.recordTypeId
             left join UniqueSecurityIdentifier usi1 on usi1.id = r.lastChangedByUserId
    
    调用查询时指定映射规则:
    Query<AllRecordsDTO> createdQuery = statelessSession.createNativeQuery(allRecordsQuery, "AllRecordsDTOMapping");
    
  • 对齐字段映射关系:无论使用哪种映射方案,都需要保证查询返回的字段顺序/别名和DTO的属性顺序/名称完全匹配,否则会出现映射失败或者属性赋值错误的问题。

内容的提问来源于stack exchange,提问作者Asif Kamran Malick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03