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

Spring Boot WebFlux中Repository转DTO返回重复数据问题求助

解决响应式请假查询API返回重复数据的问题

可能的原因及排查解决步骤

1. 实体类LeaveRequest未正确实现equals()和hashCode()

响应式数据访问框架(比如Spring Data R2DBC)依赖实体的相等性判断来处理结果去重。如果LeaveRequest的这两个方法没基于主键(比如id)实现,框架会把同一个数据库记录识别为不同对象,导致重复输出。

  • 直接给LeaveRequest添加如下实现:
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    LeaveRequest that = (LeaveRequest) o;
    return Objects.equals(id, that.id);
}

@Override
public int hashCode() {
    return Objects.hash(id);
}

2. Repository查询触发笛卡尔积

如果LeaveRequest关联了其他实体(比如员工、审批记录),查询时没加DISTINCT或关联条件错误,会触发笛卡尔积,单条记录被多次返回。

  • 检查Repository的查询方法:
    • 自定义SQL的话,添加DISTINCT关键字:
      @Query("SELECT DISTINCT lr FROM LeaveRequest lr WHERE ...")
      Flux<LeaveRequest> findByStatusAndReportingManagerId(String status, Long managerId);
      
    • 用方法名推导的话,添加Distinct注解:
      Flux<LeaveRequest> findDistinctByStatusAndReportingManagerId(String status, Long managerId);
      

3. 响应式流被重复订阅

在Service或Controller层,如果手动多次订阅同一个Flux,会导致数据被多次发射。比如ServiceImpl里不小心订阅了两次流再返回。

  • 排查代码,确保Flux只由Spring Web自动订阅,不要手动调用subscribe()后再返回流。
    • 错误示例:
      flux.subscribe(); // 多余的订阅,导致数据重复发射
      return flux.map(dto::convert);
      
    • 正确做法:直接返回转换后的Flux即可。

4. DTO转换逻辑问题

如果ViewLeaveRequestsDto未实现基于唯一标识的equals()和hashCode(),响应式框架无法识别重复的DTO对象,会输出多条相同数据。

  • 给ViewLeaveRequestsDto添加基于leaveRequestId(或对应主键字段)的相等性判断方法。

5. 角色过滤逻辑错误

检查RM角色的查询逻辑,是否不小心循环处理了查询结果,或者重复添加了数据到流中。

  • 开启SQL日志,查看实际执行的查询语句和返回条数:
    在application.yml中添加日志配置:
    logging:
      level:
        org.springframework.data.r2dbc: DEBUG
        io.r2dbc.postgresql: DEBUG # 数据库类型对应调整,比如MySQL用io.r2dbc.mysql
    
    执行请求后看日志里的SQL返回条数是否和数据库一致,就能定位是查询还是后续处理的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:15:36