当前位置: 首页 > 知识库问答 >
问题:

为一对多关系中的子表指定条件

段干茂实
2023-03-14

我有两个实体对象(A和B),它们有一对多的关系。我使用JPA(Hibernate)连接这些表并查询它们以获得特定的结果集,但在获取结果时,我为子表(B)指定的条件不适用。我是这样定义查询的:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<A> query = builder.createQuery(A.class);
Root<A> a = query.from(A.class);
Join<A, B> abJoined = a.join(A_.b);

query.distinct(true)
    .where(builder.and(
        builder.equal(a.get(A_.id), id),
        builder.equal(a.get(A_.active), 1),
        builder.equal(a.get(A_.location), 1011),
        builder.equal(a.get(A_.status), "Pending"),

        builder.equal(abJoined.get(B_.status), "Not Moved"),
        builder.greaterThan(abJoined.get(B_.detailId), 0)
    ));

当我调用entityManager时。createQuery(查询)。getResultList() 我得到实体“A”的一个实例,但当我试图通过“A”访问“B”时。getB()我为abJoined指定的两个条件不适用,我得到了所有连接到“A”的“B”实例。我还需要做些什么来应用这些标准吗?如果无法应用标准,是否有从结果集中删除“B”的相应实例的推荐方法?

如有必要,我可以提供更多代码或其他详细信息。

共有2个答案

伍心水
2023-03-14

但是,在JPA中,对于@OneTo多项关系,查询首先在主服务器上触发,所有的标准和读取都只是主记录。之后,查询被单独触发,但是但是但是...... B表条件不会包含所有条件,而是只包含一个条件,即只包含获取的主记录的主键值,即只包含一个条件“b.A_id=[从主文件中获取的主键值]”

解决方案很简单,创建一个独立的类,其中需要@OneToMany关系的字段

第一步

public class AB {

    private A a;
    private B b;  //@OneToMany with A in the Entity class definitions

public AB(){}

public AB(A a, B b){ ///Very Important to have this constructor
    this.a=a;
    this.b=b;
}

getter setter....

}

第二步

CriteriaQuery<AB> q = criteriaBuilder.createQuery(AB.class);
Root<A> fromA = criteriaQuery.from(A.class);      
List<Predicate> predicates = new ArrayList<Predicate>();         
Join<A,B> fromB = fromA.join("b", JoinType.INNER);/*"b",fieldName of B in entity Class A*/
criteriaQuery.select(criteriaBuilder.construct(AB.class,A,B));//looks AB's 2 param constr.
predicates.add(criteriaBuilder.equal(fromA.get("name"), filter.getName()));   
predicates.add(criteriaBuilder.equal(fromB.get("salary"), filter.getSalary()));
.......... 
List<AB> ABDataList = typedQuery.getResultList();  
for(AB eachABData :ABDataList){
    ....put in ur objects
    obj.setXXX(eachABData.getA().getXXX());
    obj.setYYY(eachABData.getB().getYYY());
} 

这将给出将所有标准应用于主表A的所有结果,并比较表B的主键而不是外键。

朱天逸
2023-03-14

查询用于选择查询必须返回哪些实体。但A实体永远不会是只包含其B的子集的部分实体。它们总是A的完整实例,反映A在数据库中的状态,以及A与哪个B相关。

顺便说一句,即使这是可能的(这是不可能的,而且JPA规范明确禁止),您的查询至少也必须使用fetch连接加载Bs。否则,查询只返回A的状态,并且延迟加载链接的B。

 类似资料:
  • 我需要在我的数据库中创建多个多对多的关系。 有一个“主”表,我们称之为“项目”。 然后有3个表包含“选项”。 假设我们有:品类、地域、用户。这些保存的唯一信息是项目的名称和ID。 可以将多个类别、区域和用户分配给多个项目。 因此,我有两个选项来创建这种关系: 1)为每个'选项'表创建关系表。每个表包含两列:project_id和category_id、region_id或user_id。使用这种方

  • 我在Eclipselink2.3.2中使用JPA2.0,在其中,我在产品和它们的颜色之间建立了多对多的关系。一个产品可以有多种颜色,一种颜色可以与多种产品相关联。这种关系在数据库中由三个表表示。 null 很明显,实体类有一组颜色-,它被命名为。 实体类有一组产品-,它被命名为。 我需要根据提供的与表中的颜色不匹配的从表中获取颜色列表。 对应的JPQL如下所示。 它生成以下SQL语句。 因为这将是

  • 用户表结构:用户 id、名称、用户名、密码、创建时间、更新时间 文章表结构:文章 id、标题、内容、创建时间、更新时间 关系表:文章\用户 id、文章id、用户id处于活动状态、创建时间、更新时间 标签 id、名称、用户id、创建时间、更新时间 透视表项目用户与标记的关系。表:文章\用户\标签 标签号,物品号,用户号 我想连接这些表,以便可以像这样或类似的格式访问 并且应该能够创建/更新smth,

  • 问题内容: 因此,我有以下实体: 因此,没有对的引用,这意味着我们具有单向一对多关系。我需要寻找一个by 和。也就是说,找到具有指定posId的供应商,然后在供应商的pos列表中找到一个pos。如何为此编写条件查询? 我尝试使用子查询。我的想法是创建一个子查询,该子查询将获取具有给定条件的a的所有内容。然后,主查询将那些中搜索的一个给定。 问题是我无法编写查询来获取s的s列表。显然,您不能编写以下

  • 问题内容: 使用以下模型: 如果我要查找包含至少一篇文章的订单操作,则可以按预期工作: 但是,如果要查找订单中所有商品的订单操作,正确的方法是什么? 引发错误(我理解为什么会这样)。 问题答案: 一个简单的解决方案: 这只是一个查询,但每篇文章都有一个内部联接。对于多篇文章,Willem更巧妙的解决方案应该会表现更好。