2009-10-06 169 views
16

假设我有类,如:休眠条件查询

class A { 
B getB(); 
C getC(); 
} 

class B { 
String getFoo(); 
} 

class C { 
int getBar(); 
} 

,我要筛选标准,但在不同的子类的属性两个过滤器,如:

Criteria criteriaA = session.createCriteria(A.class); 
Criteria criteriaB = criteriaA.createCriteria("b").add(Restrictions.eq("foo", "Something")); 
Criteria criteriaC = criteriaA.createCriteria("c").add(Restrictions.eq("bar", 0)); 

我想要做的就是使用“或”子句将criteriaB和criteriaC结合起来,例如:

//this does not work 
criteriaA.add(Restrictions.disjunction().add(criteriaB).add(criteriaC)); 

我该如何做到这一点?我在这里绊了一下API。

回答

24

使用aliases代替嵌套条件:

Criteria criteria = session.createCriteria(A.class) 
.createAlias("b", "b_alias") 
.createAlias("c", "c_alias") 
.add(Restrictions.disjunction() 
    .add(Restrictions.eq("b_alias.foo", "Something")) 
    .add(Restrictions.eq("c_alias.bar", "0")) 
); 
+0

别名是不必要的。 – 2009-10-06 22:17:33

+0

试试这个 - 再次感谢,国际象棋 – RMorrisey 2009-10-06 22:19:55

+0

你会怎样做这个没有别名? – RMorrisey 2009-10-06 22:20:54

4

你只需要创建一个标准的对象,像这样。

Criteria criteria = session.createCriteria(A.class); 
criteria.add(Restriction.disjunction() 
    .add(Restriction.eq("b.foo", "something")) 
    .add(Restriction.eq("c.bar", 0))); 
+0

这不起作用;我得到一个错误:org.hibernate.QueryException:无法解析属性:b.foo:com.myproject.A – RMorrisey 2009-10-06 22:34:42

+0

听起来像这只适用于一个属性级别,但不适用于我正在使用的实际过滤器。 – RMorrisey 2009-10-06 22:38:36

+0

您必须使用createQuery的createAlias。我相应地编辑了答案。 – 2012-03-12 11:55:35

3

万一别人发现它很有用,我发现了一个更复杂的答案,这似乎由API允许的问题,虽然我没有测试它ChssPly张贴了他的(简单的)解决方案之前:

DetachedCriteria bValues = DetachedCriteria.forClass(A.class); 
bValues.createCriteria("b").add(Restrictions.eq("foo", "something")); 

DetachedCriteria cValues = DetachedCriteria.forClass(A.class); 
cValues.createCriteria("c").add(Restrictions.eq("bar", 0)); 

Restrictions.or(Subqueries.in("id", bValues), Subqueries.in("id", cValues)); 
+0

有趣的是,我从来没有想过要这样试试。尽管如此,生成的查询与通过别名获取的查询会有很大的不同(可能会更慢)。但是,如果别名失败,这可能是解决sqlRestriction问题的方法。 – ChssPly76 2009-10-06 23:00:35