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

Hibernate Criteria Query:如何通过关联House对象查询Water记录?

解决通过间接关联实体查询的Criteria Query问题

你遇到的错误原因很明确:你的Water实体并没有直接持有House的引用,而是通过Flat对象间接关联的,所以直接在Water的查询根对象上获取house属性自然会抛出找不到属性的异常。

要实现根据指定House和月份查询Water记录的需求,我们需要在Criteria Query中通过关联查询遍历实体间的关系——从Water关联到Flat,再从Flat关联到House。

修改后的完整代码

public static List<Water> getAll(Date date, House house){ 
    List<Water> waterList = null; 
    Calendar myCalendar = Calendar.getInstance(); 
    myCalendar.setTime(date); 
    myCalendar.set(Calendar.DAY_OF_MONTH, 1); 
    Date monthStart = new java.sql.Date(myCalendar.getTimeInMillis()); 
    myCalendar.add(Calendar.DAY_OF_MONTH, (myCalendar.getMaximum(Calendar.DAY_OF_MONTH) - myCalendar.get(Calendar.DAY_OF_MONTH))); 
    Date monthEnd = new java.sql.Date(myCalendar.getTimeInMillis()); 

    Session sess = mainApp.getSessionFactory().openSession(); 
    Transaction tx = null; 
    try { 
        tx = sess.beginTransaction(); 
        // create criteria builder 
        CriteriaBuilder builder = sess.getCriteriaBuilder(); 
        // create criteria 
        CriteriaQuery<Water> query = builder.createQuery(Water.class); 
        // specify criteria root 
        Root<Water> root = query.from(Water.class);
        
        // 关键步骤:关联Water到Flat,再通过Flat关联到House
        Join<Water, Flat> flatJoin = root.join("flat"); // 这里的"flat"要和Water实体中Flat属性的名称一致
        
        query.select(root) 
             .where(builder.and(
                 builder.equal(flatJoin.get("house"), house), // 从关联的Flat中获取House进行匹配
                 builder.greaterThanOrEqualTo(root.get("date"), monthStart), 
                 builder.lessThanOrEqualTo(root.get("date"), monthEnd)
             )); 

        waterList = sess.createQuery(query).getResultList(); 
        tx.commit(); 
    } catch (Exception e) { 
        if (tx != null) tx.rollback(); 
        e.printStackTrace(); 
    } finally { 
        sess.close(); 
    } 
    return waterList; 
}

关键修改说明

  1. 添加关联查询:通过root.join("flat")建立Water到Flat的关联,这里的字符串"flat"必须和你Water实体类中持有Flat引用的属性名称完全一致(比如如果实体里的属性是private Flat flat;,那这里就用"flat")。
  2. 修改House匹配条件:将原来的builder.equal(root.get("house"), house)替换为builder.equal(flatJoin.get("house"), house),通过关联后的Flat对象来匹配目标House。

额外注意事项

  • 确保Flat实体类中持有House引用的属性名称是"house"(如果属性名是private House myHouse;,那这里就要改成flatJoin.get("myHouse"))。
  • 如果你的关联是延迟加载,这个查询会自动触发关联查询,不会有N+1问题,因为Criteria的join会生成一条JOIN语句来查询关联数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:33