原生SQL多JOIN查询出现重复ID别名错误的问题求助
解决方案
问题根源
你遇到的NonUniqueDiscoveredSqlAliasException是因为原生SQL中使用了select *,查询返回结果包含了reports、patients、lab_technicians三个表的所有字段,而这三个表都存在名为id的列(reports自身的id,patients和lab_technicians继承自Person的id)。Hibernate在自动映射结果到Report实体时,无法区分这些重复的id别名,因此抛出异常。
另外你的SQL参数写法存在问题:%:patientName%这种格式无法被Hibernate正确解析参数,会导致参数绑定失效,还存在SQL注入风险。
修复步骤
1. 仅查询Report表的字段
不需要查询关联表的所有字段,只需查询reports表的字段(用r.*),因为最终要返回的是Report实体。
2. 正确绑定模糊查询参数
使用concat('%', :参数名, '%')拼接模糊查询的通配符,让Hibernate正确处理参数绑定。
修改后的Repository代码
@Query(value = "select r.* from reports r " + "join patients p on r.patient_id = p.id " + "join lab_technicians lt on r.lab_technician_id = lt.id " + "where p.name like concat('%', :patientName, '%') " + "and lt.name like concat('%', :labTechnicianName, '%') " + "and p.identity_no like concat('%', :patientIdentityNo, '%')", nativeQuery = true) List<Report> findBySearch(@Param("patientName") String patientName, @Param("labTechnicianName") String labTechnicianName, @Param("patientIdentityNo") String patientIdentityNo);
补充说明
- 若确实需要关联表的字段,可以显式指定列名并给重复字段起别名,比如
p.id as patient_id, lt.id as technician_id,但你返回的是Report实体,这种场景一般不需要。 - 将List改成Set无法解决该问题,因为异常是SQL字段别名重复导致的,和集合类型无关。
内容的提问来源于stack exchange,提问作者Codedator
相关产品推荐
相关产品推荐

