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);
- 自定义SQL的话,添加
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中添加日志配置:
执行请求后看日志里的SQL返回条数是否和数据库一致,就能定位是查询还是后续处理的问题。logging: level: org.springframework.data.r2dbc: DEBUG io.r2dbc.postgresql: DEBUG # 数据库类型对应调整,比如MySQL用io.r2dbc.mysql
内容的提问来源于stack exchange,提问作者Nisha
相关产品推荐
相关产品推荐

