Spring Boot+Hibernate查询报错:发现重复SQL别名[id]求助
核心问题分析
你的错误源于两个关键点:一是SQL的JOIN条件逻辑错误,二是SELECT *导致结果集出现重复列名;同时实体类的关联映射设计也不符合一对多关系的规范。
解决方案1:修复SQL语句(适配现有中间表结构)
你的中间表user_private_messages关联private_messages的字段应该是private_message_id(而非自身主键id),同时要避免用SELECT *拉取所有列,只查询private_messages的字段即可避免重复列名冲突:
@Query(value = "SELECT pm.* " + "FROM MessagingApp.private_messages pm " + "LEFT JOIN MessagingApp.user_private_messages upm ON pm.id = upm.private_message_id " + "WHERE upm.user_id = ?1 AND pm.recipient_id = ?2 " + "ORDER BY pm.created_at DESC;", nativeQuery = true) public List<PrivateMessage> retrieveAllBetweenTwoUsers(Long senderId, Long receiverId);
解决方案2:修正实体类关联映射(更合理的一对多设计)
当前你用@JoinTable配置User和PrivateMessage的关联,这是多对多的配置方式,但实际场景是一个用户发送多条私信,属于一对多关系,应该直接在PrivateMessage中用@JoinColumn关联User的外键,不需要中间表:
修改PrivateMessage类的关联字段:
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") // 对应private_messages表中的user_id外键列 private User user;
此时SQL可以简化为:
@Query(value = "SELECT * FROM MessagingApp.private_messages " + "WHERE user_id = ?1 AND recipient_id = ?2 " + "ORDER BY created_at DESC;", nativeQuery = true) public List<PrivateMessage> retrieveAllBetweenTwoUsers(Long senderId, Long receiverId);
这种设计既解决了重复列名问题,也符合一对多关系的数据库规范,查询效率更高。
为什么之前加别名无效?
因为你使用了SELECT *,即使给单个列加别名,*仍然会返回所有列(包括中间表的id),导致结果集中出现两个id列,Hibernate无法区分这两个同名列,因此报错。只有明确指定需要的字段(如pm.*),才能避免重复列的出现。
内容的提问来源于stack exchange,提问作者it_tony
相关产品推荐
相关产品推荐

