Spring Boot中findAllBy查询仅返回单条数据问题求助
问题排查与解决方案
1. 原生SQL查询的参数绑定错误
你的原生@Query语句存在逻辑错误:
@Query(value = "SELECT * FROM medical_history WHERE patient_id = id",nativeQuery = true) List<MedicalHistory> findAllByPatientId(Long id);
这里的id会被数据库解析为medical_history表自身的主键id,而非你传入的参数。实际执行的SQL是查询patient_id等于自身主键id的记录,自然只会返回最多一条数据。
修复方式:使用参数占位符绑定传入的参数,二选一即可:
// 方式1:命名参数绑定 @Query(value = "SELECT * FROM medical_history WHERE patient_id = :patientId", nativeQuery = true) List<MedicalHistory> findAllByPatientId(@Param("patientId") Long patientId); // 方式2:位置参数绑定 @Query(value = "SELECT * FROM medical_history WHERE patient_id = ?1", nativeQuery = true) List<MedicalHistory> findAllByPatientId(Long patientId);
2. 实体类与数据库列名映射不匹配
你的MedicalHistory实体中,patientId字段的@JoinColumn指定的列名是"patientId",但数据库表实际列名是patient_id(从原生SQL的写法可判断)。映射不匹配会导致JPA生成的查询SQL无法正确关联字段,返回错误结果集。
修复实体类的映射配置:
@ManyToOne @JoinColumn(name= "patient_id") // 改为数据库实际列名 private Patient patientId;
3. Repository方法冗余导致歧义
你的MedicalHistoryRepository中存在两个功能重复的方法:findMedicalHistoriesByPatientId和findAllByPatientId,这会导致Spring Data JPA生成SQL时出现歧义。建议保留一个正确的方法,删除冗余定义:
public interface MedicalHistoryRepository extends JpaRepository<MedicalHistory, Long> { // 修复映射后,Spring Data JPA可自动生成正确的查询SQL List<MedicalHistory> findAllByPatientId(Long patientId); // 也可使用修复后的原生SQL方法,二选一即可 // @Query(value = "SELECT * FROM medical_history WHERE patient_id = ?1", nativeQuery = true) // List<MedicalHistory> findAllByPatientId(Long patientId); }
4. 业务方法的空指针风险优化
虽然这不是查询返回单条数据的直接原因,但getPatient.get()在patientRepository.findByNin返回空时会抛出异常,建议添加空判断:
public List<MedicalHistory> getPatientMedicalRecords(PatientDto patientDto) { return patientRepository.findByNin(patientDto.getNin()) .map(patient -> medicalHistoryRepository.findAllByPatientId(patient.getPatientId())) .orElse(Collections.emptyList()); }
验证步骤
- 确认数据库
medical_history表中存在多条patient_id相同的记录 - 修复上述问题后,重启项目测试接口,检查返回的List是否包含所有符合条件的记录
内容的提问来源于stack exchange,提问作者TechNewPy
相关产品推荐
相关产品推荐

