You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:15:05