使用@NamedNativeQuery与@SqlResultSetMapping时类型转换异常排查
原因分析与解决办法
核心问题
Spring Data JPA没有识别到你配置的@NamedNativeQuery和对应的结果集映射,导致默认将查询结果封装成TupleBackedMap,后续尝试把这个Map转成LightAssetWithQtyDto时找不到合适的转换器,从而抛出异常。
问题出在命名查询的匹配逻辑上:
- 你定义的
@NamedNativeQuery名称是AssetEntity.findAllAssetsWithQty - 但Repository中的方法名是
findAllAssetsWithQty
虽然Spring Data JPA默认支持实体类名.方法名的命名查询规则,但当返回类型是DTO而非实体类时,JPA不会自动关联到你配置的结果集映射,必须明确指定使用该命名查询。
修复方案
方案1:修改命名查询名称
去掉命名查询名称中的AssetEntity.前缀,让它和Repository方法名完全一致:
@NamedNativeQueries( @NamedNativeQuery(name = "findAllAssetsWithQty", resultSetMapping = "LightAssetWithQtyDtoMapping", query = "SELECT a.id, a.stock_symbol, sum(t.quantity) AS total " + "FROM asset a " + "RIGHT JOIN \"transaction\" t ON a.id = t.asset_id " + "GROUP BY a.stock_symbol, a.id HAVING sum(t.quantity) > 0" ) )
方案2:在Repository方法上显式指定命名查询
如果不想修改命名查询名称,直接在Repository方法上添加@Query注解,明确指定要使用的命名查询:
@Repository public interface AssetRepository extends CrudRepository<AssetEntity, Integer> { @Query(name = "AssetEntity.findAllAssetsWithQty", nativeQuery = true) List<LightAssetWithQtyDto> findAllAssetsWithQty(); }
额外提醒
当前你的@ConstructorResult中列的顺序和DTO构造器的参数顺序是匹配的(id → stock_symbol → total 对应构造器的id → stockSymbol → total),这部分没问题,后续如果调整列顺序或构造器参数,需要同步修改两者,避免出现参数不匹配的问题。
内容的提问来源于stack exchange,提问作者Clem
相关产品推荐
相关产品推荐

