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

如何使用Hibernate Criteria实现Flight关联Airport两次的SQL查询?

正确实现Hibernate Criteria对应指定SQL查询的方法

原SQL的逻辑是:通过关联flight表与两个airport表(分别对应出发地和目的地),筛选出出发地城镇为minsk、目的地城镇为pinsk的所有航班记录。

常见问题原因

你之前生成的查询出现1=1无效条件,大概率是因为关联实体时未正确设置别名,或者添加筛选条件时引用了错误的属性路径,导致Hibernate无法解析你的条件,最终用1=1替代无效约束。

正确实现方式

首先假设你的实体类结构如下(需与数据库表对应):

  • Flight实体:包含fromAirport(对应flight.from_id,@ManyToOne关联Airport)、toAirport(对应flight.to_id,@ManyToOne关联Airport)属性
  • Airport实体:包含id、town属性

方式1:使用JPA Criteria API(推荐,兼容JPA规范)

// 获取EntityManager实例(根据你的项目方式获取,比如Spring注入)
EntityManager em = ...;

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Flight> cq = cb.createQuery(Flight.class);
Root<Flight> flightRoot = cq.from(Flight.class);

// 关联出发机场,设置别名a1(内关联,对应SQL的INNER JOIN)
Join<Flight, Airport> a1 = flightRoot.join("fromAirport", JoinType.INNER);
// 关联到达机场,设置别名a2
Join<Flight, Airport> a2 = flightRoot.join("toAirport", JoinType.INNER);

// 添加筛选条件:同时满足出发地是minsk,目的地是pinsk
cq.where(
    cb.and(
        cb.equal(a1.get("town"), "minsk"),
        cb.equal(a2.get("town"), "pinsk")
    )
);

// 执行查询获取结果
List<Flight> flights = em.createQuery(cq).getResultList();

方式2:使用Hibernate原生Criteria API(旧版Session方式)

如果你的项目仍在使用Hibernate的Session API,可按以下方式实现:

// 获取Session实例
Session session = ...;

Criteria criteria = session.createCriteria(Flight.class);
// 关联出发机场并设置别名a1
criteria.createAlias("fromAirport", "a1");
// 关联到达机场并设置别名a2
criteria.createAlias("toAirport", "a2");

// 添加组合筛选条件
criteria.add(Restrictions.and(
    Restrictions.eq("a1.town", "minsk"),
    Restrictions.eq("a2.town", "pinsk")
));

// 执行查询
List<Flight> flights = criteria.list();

关键注意点

  • 确保实体类中的关联属性名称(比如fromAirport、toAirport)与你在Criteria中引用的名称完全一致
  • 别名(a1、a2)要在关联时正确设置,且条件中要通过别名引用关联实体的属性
  • 如果使用字段名而非属性名(比如直接用from_id),会导致Hibernate无法映射,同样可能生成无效条件

内容的提问来源于stack exchange,提问作者Singularity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:25:23