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

JPA Repository nativeQuery带Pageable时size=1关联查询报错如何解决

错误原因

Spring Data JPA 对原生查询自动生成 count 查询的逻辑存在局限性,遇到带表别名、GROUP BY 聚合、自定义字段别名的查询时,会直接粗暴替换原查询的 SELECT 部分为 count(第一个查询项的前缀),你的原查询第一个返回字段是 ppd.userId,所以框架自动生成了非法的 select count(ppd) ... 语句,最终触发字段不存在报错。

解决方案

提供两种可选方案,可根据业务需求选择:

方案1:自定义 countQuery 保留 Page 分页特性

如果你的业务需要用到 Page 自带的总条数、总页数等元数据,直接在 @Query 注解中添加 countQuery 参数,写入符合逻辑的计数语句即可,计数语句仅需要统计符合筛选条件的分组总数量,写法如下:

@Query(value = "SELECT ppd.userId, AVG(Coalesce(sm.score, 0)) AS avgScore " +
            " FROM Table1 ppd " +
            " LEFT JOIN Table2 sm ON sm.userId = ppd.userId AND sm.created BETWEEN :start AND :end " +
            " WHERE ppd.someId IN (:IdList) GROUP BY ppd.userId",
       countQuery = "SELECT COUNT(DISTINCT ppd.userId) " +
            " FROM Table1 ppd " +
            " LEFT JOIN Table2 sm ON sm.userId = ppd.userId AND sm.created BETWEEN :start AND :end " +
            " WHERE ppd.someId IN (:IdList)",
       nativeQuery = true)
Page<MyDtoProjection> getAvg(@Param("IdList") List<String> IdList,
                             @Param("start") Long start,
                             @Param("end") Long end,
                             Pageable pageable);

你也可以用子查询写法实现 countQuery,结果完全一致:

SELECT COUNT(*) FROM (
    SELECT ppd.userId FROM Table1 ppd 
    LEFT JOIN Table2 sm ON sm.userId = ppd.userId AND sm.created BETWEEN :start AND :end 
    WHERE ppd.someId IN (:IdList) GROUP BY ppd.userId
) t

方案2:返回List避免生成count查询(更适配你的场景)

你的业务已经固定了 limit=1,不需要总页数、总条数等分页元数据的话,直接把方法返回值从 Page<MyDtoProjection> 改成 List<MyDtoProjection> 即可,框架不会再自动生成 count 查询,原有查询逻辑、Pageable 的分页和排序能力完全不受影响,你拿到结果后直接取第一个元素即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:54:02