简体   繁体   English

Hibernate 标准对儿童有限制

[英]Hibernate criteria with restrictions on children

I have a Hibernate criteria call that I want to execute in one SQL statement.我有一个 Hibernate 标准调用,我想在一个 SQL 语句中执行。 What I'm trying to do is select instances of Parent that have Children with a property in a range of values (SQL IN clause), all while loading the children using an outer join.我正在尝试做的是 select 的 Parent 实例,这些实例的 Child 具有一系列值(SQL IN 子句)的属性,同时使用外连接加载孩子。 Here's what I have so far:这是我到目前为止所拥有的:

 Criteria c = session.createCriteria(Parent.class);

 c.createAlias("children", "c", CriteriaSpecification.LEFT_JOIN)
          .setFetchMode("c", FetchMode.JOIN)
          .add(Restrictions.in("c.property", properties));

 c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

 return c.list();

Here's some sample data:以下是一些示例数据:

Parent
Parent ID
A
B
C

Children
Child ID    Parent ID   property
...         A           0
...         A           2
...         A           7
...         B           1
...         C           1
...         C           2
...         C           3

What I want to do is return the parents and ALL their children if one of the children has a property equal to my bind parameter(s).如果其中一个孩子的属性等于我的绑定参数,我想要做的是返回父母和他们的所有孩子。 Let's assume properties is an array containing {2}.假设 properties 是一个包含 {2} 的数组。 In this case, the call will return parents A and C but their child collections will contain only element 2. Ie Parent[Children]:在这种情况下,调用将返回父母 A 和 C 但他们的孩子 collections 将只包含元素 2。即 Parent[Children]:

A[2] & C[2] A[2] 和 C[2]

What I want is:我想要的是:

A[0, 2, 7] & C[1, 2 3] A[0, 2, 7] & C[1, 2 3]

If this is not a bug, it seems to be a broken semantic.如果这不是一个错误,它似乎是一个损坏的语义。 I don't see how calling A.getChildren() or C.getChildren() and returning 1 record would ever be considered correct -- this is not a projection.我看不出调用 A.getChildren() 或 C.getChildren() 并返回 1 条记录会被认为是正确的——这不是预测。 Ie if I augment the query to use the default select fetch, it returns the proper children collections, albiet with a multitude of queries:即,如果我增加查询以使用默认的 select 提取,它会返回正确的子 collections,尽管有大量查询:

  c.createAlias("children", "c").add(
      Restrictions.in("c.property", properties));

Is this a bug?这是一个错误吗? If not, how can I achieve my desired result?如果没有,我怎样才能达到我想要的结果?

        Criteria c = session.createCriteria(Parent.class);

    c.createAlias("children", "children");
    c.add(Restrictions.in("children.property", properties));

     c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

     return c.list();

I would start the Criteria with the child class.我将从子 class 开始标准。 You'll get a list with all the children, and then you can iterate and get the parent for each children.你会得到一个包含所有孩子的列表,然后你可以迭代并为每个孩子获取父母。

This can be done in work around way.这可以通过解决方法来完成。

Criteria c1 = session.createCriteria(Child.class);
c1.add(Restrictions.in("property", properties));
c1.setProjection( Projections.distinct( Projections.property( "parentId" ) ) );
List<Integer> parentIds = c1.list();

Criteria c2 = session.createCriteria(Parent.class);
c2.createAlias("children", "children");
c2.add(Restrictions.in("id", parentIds));
return c2.list();

getChildren() is just the name of the getter/setter, your query will determine how the objects get populated. getChildren() 只是 getter/setter 的名称,您的查询将确定对象的填充方式。

I'm going to guess here that the first part spits out我猜这里第一部分吐出来了

SELECT * FROM Parent 
INNER JOIN Child c ON ... 
WHERE c.property in (x,y,z) 

which doesn't get you what you want.这不会让你得到你想要的。 What'd you'd want to do if you were writing this in raw SQL is this:如果您在原始 SQL 中编写此内容,您会想要做什么:

SELECT * FROM Parent  
WHERE ParentID IN (SELECT DISTINCT parentID FROM Child WHERE  c.property in (x,y,z))

rearranging your criteria appropriately might do the trick if the last one isn't producing this query.如果最后一个没有产生此查询,则适当地重新排列您的标准可能会起到作用。 (Could you also post what hibernate is generating for each?) (您还可以发布 hibernate 为每个生成的内容吗?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM