如何编写查询获取两表全列并解决别名重复异常?
解决NonUniqueDiscoveredSqlAliasException的可行方案
核心原因
两张表都包含id列,使用SELECT *会返回两个同名的id字段,Hibernate无法区分重复的列别名,因此抛出该异常。
具体解决办法
1. 给重复列指定唯一别名
无需逐个列出所有列,只需给重复的id列单独重命名,确保返回的字段别名唯一:
SELECT t1.*, t2.id AS t2_id, t2.* FROM Table1 t1 INNER JOIN Table2 t2 ON t1.id = t2.t1_id WHERE t1.search_key IN ('12345')
注意:必须把
t2.id AS t2_id放在t2.*前面,否则t2.*中的原始id会覆盖别名,仍会出现重复问题。
2. 结合模型类构造函数映射
如果目标模型类有对应构造函数,可在查询中明确指定重复列的别名,其余字段按名称自动匹配:
@Query(value="SELECT t1.id, t1.search_key, t2.id AS t2_id, t2.t1_id, t1.*, t2.* FROM Table1 t1 INNER JOIN Table2 t2 ON t1.id = t2.t1_id WHERE t1.search_key IN (:searchKeys)", nativeQuery=true) List<YourModel> getCombinedData(@Param("searchKeys") List<String> searchKeys);
重复列需单独声明别名,非重复列利用通配符简化编写,只要模型类字段名与数据库列名一致即可自动映射。
3. 使用SqlResultSetMapping定义映射规则
在实体类或配置类中定义结果集映射规则,明确指定重复列的别名与模型类字段的对应关系:
@SqlResultSetMapping( name = "CombinedDataMapping", classes = @ConstructorResult( targetClass = YourModel.class, columns = { @ColumnResult(name = "id", type = Long.class), @ColumnResult(name = "t2_id", type = Long.class), // 按顺序或名称配置其他字段映射 } ) )
之后在查询中引用该映射:
@Query(value="SELECT t1.*, t2.id AS t2_id, t2.* FROM Table1 t1 INNER JOIN Table2 t2 ON t1.id = t2.t1_id WHERE t1.search_key IN ('12345')", nativeQuery=true, resultSetMapping="CombinedDataMapping") List<YourModel> getCombinedData();
4. 临时配置实体关联改用HQL查询
如果允许临时修改实体类,可给Table1添加与Table2的关联关系,用HQL自动处理字段别名:
// 在Table1实体类中添加关联 @OneToMany(mappedBy = "t1") private List<Table2> table2List; // 编写HQL查询 @Query("SELECT t1, t2 FROM Table1 t1 JOIN t1.table2List t2 WHERE t1.searchKey IN (:searchKeys)") List<Object[]> getCombinedData(@Param("searchKeys") List<String> searchKeys);
查询返回
Object[]数组,每个数组元素对应Table1和Table2的实体对象,后续可手动转换为目标模型类。
内容的提问来源于stack exchange,提问作者anurag tripathi
相关产品推荐
相关产品推荐

