我有一个Hibernate条件调用,我想在一个SQL语句中执行。我正在尝试做的是选择Parent的实例,其中Child具有一系列值的属性(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
我想要做的是如果其中一个孩子的属性等于我的绑定参数,则返回父母及其所有孩子。我们假设属性是一个包含{2}的数组。在这种情况下,调用将返回父项A和C,但它们的子集合将仅包含元素2。父[儿童]:
A [2]& C [2]
我想要的是:
A [0,2,7]& C [1,2 3]
如果这不是一个错误,它似乎是一个破碎的语义。我不知道如何调用A.getChildren()或C.getChildren()并返回1条记录将被认为是正确的 - 这不是一个投影。即如果我扩充查询以使用默认的select fetch,它会返回正确的子集合,带有大量查询的albiet:
c.createAlias("children", "c").add(
Restrictions.in("c.property", properties));
这是一个错误吗?如果没有,我怎样才能达到预期的效果?
答案 0 :(得分:5)
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();
答案 1 :(得分:1)
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))
如果最后一个不生成此查询,正确地重新排列您的标准可能会有所帮助。 (你还可以发布hibernate为每个人生成的内容吗?)
答案 2 :(得分:0)
我会在子课上开始Criteria。您将获得包含所有孩子的列表,然后您可以迭代并获得每个孩子的父母。
答案 3 :(得分: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();