Java JPA Hibernate:如何用Criteria Query关联带嵌入式ID的实体
用Criteria Query实现无映射关联的左连接方案
你这种情况是因为实体之间没配置JPA关联映射,但完全可以通过Criteria API手动指定连接条件来实现左连接,下面是具体实现:
完整代码示例
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // 用Tuple可以同时获取两个实体的查询结果,也可以换成你需要的DTO或单个实体 CriteriaQuery<Tuple> query = cb.createTupleQuery(); // 定义两个实体的Root节点 Root<EntityA> rootA = query.from(EntityA.class); Root<EntityB> rootB = query.from(EntityB.class); // 创建左连接,手动指定关联条件:EntityA.id = EntityB.id.entityAId Join<EntityA, EntityB> leftJoin = rootA.join(rootB, JoinType.LEFT, cb.equal(rootA.get("id"), rootB.get("id").get("entityAId"))); // 选择需要返回的字段,这里直接选整个实体 query.multiselect(rootA, rootB); // 加上连接条件,确保数据正确关联 query.where(cb.equal(rootA.get("id"), rootB.get("id").get("entityAId"))); // 执行查询 List<Tuple> results = entityManager.createQuery(query).getResultList(); // 遍历处理结果 for (Tuple tuple : results) { EntityA entityA = tuple.get(rootA); EntityB entityB = tuple.get(rootB); // 这里写你的业务逻辑 }
关键点解释
- Root节点初始化:分别获取两个实体的Root,作为查询的起始点。
- 手动左连接:用
rootA.join()的重载方法,指定连接类型为LEFT,同时传入自定义的关联条件,对应你原生SQL里的ON子句。 - 结果选择:用
multiselect可以同时返回两个实体的数据,如果你只需要部分字段,也可以指定具体字段(比如rootA.get("name")、rootB.get("order"))。
可选优化:添加JPA关联映射
如果之后经常要做这种关联查询,建议直接在EntityA里配置关联映射,这样后续查询会更简单:
// 在EntityA类中添加以下代码 @OneToMany @JoinColumn(name = "entity_A_id", referencedColumnName = "id") private List<EntityB> entityBs;
配置后,Criteria Query的左连接就可以简化成:
Root<EntityA> rootA = query.from(EntityA.class); rootA.join("entityBs", JoinType.LEFT);
不用再手动写关联条件,更符合JPA的使用习惯。
内容的提问来源于stack exchange,提问作者Lê Phương Duy PH 2 0 7 3 2
相关产品推荐
相关产品推荐

