Hibernate 5.4.3是否支持用Criteria Builder转换带EXISTS子查询的CASE语句
Hibernate 5.4.3 CASE WHEN EXISTS 子查询Criteria支持说明
核心结论
Hibernate 5.4.3作为JPA Provider已支持通过Criteria Builder构造CASE WHEN嵌套EXISTS子查询的逻辑,你提到的旧版本不支持的结论仅适用于Hibernate 5.2及更早版本,该场景在5.3版本起已完成修复优化,5.4.3可正常使用。
核心逻辑构造示例
你所需的CASE部分可以通过以下Criteria API逻辑实现:
// 假设b1对应实体类为Stats,statuses对应实体类为Status CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<StatsResultDTO> query = cb.createQuery(StatsResultDTO.class); Root<Stats> b1Root = query.from(Stats.class); // 构造三个EXISTS子查询 Subquery<Integer> existsA = query.subquery(Integer.class); Root<Status> aRootA = existsA.from(Status.class); existsA.select(cb.literal(1)) .where(cb.equal(aRootA.get("id2"), b1Root.get("id")), cb.equal(aRootA.get("status"), "A")); Subquery<Integer> existsB = query.subquery(Integer.class); Root<Status> aRootB = existsB.from(Status.class); existsB.select(cb.literal(1)) .where(cb.equal(aRootB.get("id2"), b1Root.get("id")), cb.equal(aRootB.get("status"), "B")); Subquery<Integer> existsC = query.subquery(Integer.class); Root<Status> aRootC = existsC.from(Status.class); existsC.select(cb.literal(1)) .where(cb.equal(aRootC.get("id2"), b1Root.get("id")), cb.equal(aRootC.get("status"), "C")); // 构造CASE表达式 Expression<String> overStatus = cb.selectCase() .when(cb.exists(existsA), "TEST1") .when(cb.exists(existsB), "TEST1") .when(cb.exists(existsC), "TEST2") .otherwise(""); // 后续拼接其余查询字段、排序、分页逻辑即可
额外说明
- 如果你使用JPQL写
@Query注解查询,5.4版本也支持直接编写CASE WHEN EXISTS语法,无需特殊兼容处理 - 构造时注意使用实体类的属性名而非数据库表的列名,确保实体和表映射关系正确
内容的提问来源于stack exchange,提问作者miroana
相关产品推荐
相关产品推荐

