创建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:JPQL构造器表达式(无额外注解依赖,推荐)
将查询改写为JPQL语法,在select后直接调用DTO的全参构造方法,注意字段顺序需和DTO全参构造的参数顺序完全一致,示例语法如下:
注:上述JPQL中的关联属性需要和你Record实体中定义的关联字段名保持一致。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);
2. 方案2:原生SQL + @SqlResultSetMapping 注解
在AllRecordsDTO类上添加结果集映射注解,配置字段与DTO属性的对应关系:
同时给原生SQL的所有字段添加与上述配置一致的别名:@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 { // 原有类代码不变 }
调用查询时指定映射规则: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.lastChangedByUserIdQuery<AllRecordsDTO> createdQuery = statelessSession.createNativeQuery(allRecordsQuery, "AllRecordsDTOMapping"); - 方案1:JPQL构造器表达式(无额外注解依赖,推荐)
- 对齐字段映射关系:无论使用哪种映射方案,都需要保证查询返回的字段顺序/别名和DTO的属性顺序/名称完全匹配,否则会出现映射失败或者属性赋值错误的问题。
内容的提问来源于stack exchange,提问作者Asif Kamran Malick
相关产品推荐
相关产品推荐

