Spring Data JPA多对多关系中投影类实例化失败问题
问题分析与解决
错误原因
你遇到的构造函数不匹配错误,根源在于JPQL查询里的JOIN g.categories c:
- 这个JOIN会生成申诉(Grievance)和分类(Category)的笛卡尔积,每条记录对应一个申诉+单个分类的组合。
- 此时查询中的
g.categories会被解析为单个Category实例,而非DTO构造函数期望的List<Category>类型,导致参数签名不匹配,触发错误。 - 同时这种写法还会返回重复的申诉数据(每个分类对应一条相同申诉记录)。
修正方案
1. 调整JPQL查询
去掉多余的c别名,改用LEFT JOIN FETCH来关联抓取分类列表,既确保分类数据被加载,又避免笛卡尔积重复:
@Query("SELECT new com.rnsit.studentgrievance.dto.student.StudentGrievances(g.id, g.title, g.grievanceStatus, g.askedBy, g.asked, g.modified, g.timeTaken, g.categories) FROM Grievance g LEFT JOIN FETCH g.categories WHERE g.student.usn = :usn") List<StudentGrievances> getGrievancesByUsn(String usn);
LEFT JOIN FETCH会一次性加载申诉及其关联的所有分类列表,不会生成重复的申诉记录。- 不需要显式JOIN分类表来筛选(你的查询也没用到分类筛选条件),直接通过Grievance的关联关系获取分类列表即可。
2. 额外检查
确保Grievance实体中确实存在timeTaken字段(你的实体代码片段里未展示,但DTO和查询中都用到了,需保证字段存在且类型匹配)。
内容的提问来源于stack exchange,提问作者yoo
相关产品推荐
相关产品推荐

