8

我有一个要在一个 SQL 语句中执行的 Hibernate 条件调用。我正在尝试做的是选择具有一系列值(SQL IN 子句)中的属性的子级的父级实例,同时使用外连接加载子级。这是我到目前为止所拥有的:

 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();

以下是一些示例数据:

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

如果其中一个孩子的属性等于我的绑定参数,我想要做的是返回父母和他们的所有孩子。假设 properties 是一个包含 {2} 的数组。在这种情况下,调用将返回父级 A 和 C,但它们的子集合将仅包含元素 2。即 Parent[Children]:

A[2] 和 C[2]

我想要的是:

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

如果这不是一个错误,它似乎是一个损坏的语义。我看不出调用 A.getChildren() 或 C.getChildren() 并返回 1 条记录会被认为是正确的——这不是预测。即,如果我增加查询以使用默认选择提取,它会返回正确的子集合,尽管有大量查询:

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

这是一个错误吗?如果没有,我怎样才能达到我想要的结果?

4

4 回答 4

6
        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();
于 2014-03-30T09:51:03.310 回答
0

getChildren() 只是 getter/setter 的名称,您的查询将确定对象的填充方式。

我猜这里第一部分吐出来了

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

这不会让你得到你想要的。如果您用原始 SQL 编写此代码,您想要做的是:

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

如果最后一个没有产生此查询,则适当地重新排列您的标准可能会起到作用。(您还可以发布每个休眠生成的内容吗?)

于 2011-08-10T00:01:38.507 回答
0

我会从子类开始标准。你会得到一个包含所有孩子的列表,然后你可以迭代并为每个孩子获取父母。

于 2013-04-02T10:47:20.750 回答
0

这可以通过解决方法来完成。

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();
于 2015-07-02T12:11:15.077 回答