Hibernate别名自动更新问题求助(javax.persistence.criteria.Selection.alias)
Hibernate/JPA Criteria API 别名冲突问题解决
问题原因
你遇到的报错是因为Hibernate Criteria API对同一Root的同一属性,多次调用get()会返回同一个Expression实例。你先后给这个实例设置了"SELECT"和"GROUP"两个别名,后一次会覆盖前一次,导致multiselect中的表达式别名变成"GROUP",和group by里的表达式别名重复,触发报错。
解决方案
根本上,group by子句不需要为表达式设置别名(分组依据是列本身,而非别名),只需为select中的表达式设置别名即可。修改后的代码如下:
// 仅为SELECT部分的表达式设置别名 Expression<?> poSelect = PO_details.get(PO_number); poSelect.alias("SELECT"); // GROUP BY部分的表达式无需设置别名 Expression<?> poGroup = PO_details.get(PO_number); criteriaQuery.multiselect(poSelect); criteriaQuery.groupBy(poGroup);
如果需要更清晰地处理查询结果,推荐使用Tuple查询来明确获取别名对应的结果:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // 创建Tuple类型的查询 CriteriaQuery<Tuple> criteriaQuery = cb.createTupleQuery(); Root<PO_details> PO_details = criteriaQuery.from(PO_details.class); Expression<?> poNumber = PO_details.get(PO_number); // 为SELECT项指定别名 criteriaQuery.multiselect(poNumber.alias("SELECT")); criteriaQuery.groupBy(poNumber); // 执行查询并获取结果 List<Tuple> results = entityManager.createQuery(criteriaQuery).getResultList(); for (Tuple tuple : results) { // 通过别名获取对应值 Object poNum = tuple.get("SELECT"); // 后续业务处理 }
如果确实需要两个独立的Expression实例(特殊场景),可以通过CriteriaBuilder的函数包装来生成不同实例:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); Expression<?> poSelect = cb.function("CAST", String.class, PO_details.get(PO_number)); poSelect.alias("SELECT"); Expression<?> poGroup = PO_details.get(PO_number); poGroup.alias("GROUP"); criteriaQuery.multiselect(poSelect); criteriaQuery.groupBy(poGroup);
内容的提问来源于stack exchange,提问作者Pinkey Bartake
相关产品推荐
相关产品推荐

