【问题标题】:Hibernate criteria query on different properties of different objectsHibernate条件查询不同对象的不同属性
【发布时间】:2010-12-04 10:36:43
【问题描述】:

假设我有这样的类:

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

class B {
 String getFoo();
}

class C {
 int getBar();
}

我想过滤 A 上的条件,不同子类属性上的两个过滤器,例如:

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

我想要做的是使用“或”子句将标准 B 和标准 C 结合起来,例如:

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

我怎样才能做到这一点?我在这里的 API 有点磕磕绊绊。

【问题讨论】:

    标签: java hibernate criteria


    【解决方案1】:

    如果其他人觉得它有用,我会找到一个更复杂的答案来解决这个问题,这似乎是 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));
    

    【讨论】:

    • 有趣,我从没想过要这样尝试。但是,生成的查询将与通过别名获得的查询完全不同(并且可能更慢)。但是,如果别名失败,这可能是解决您的 sqlRestriction 问题的方法。
    【解决方案2】:

    您只需要像这样创建一个条件对象。

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

    【讨论】:

    • 这不起作用;我收到如下错误:org.hibernate.QueryException: could not resolve property: b.foo of: com.myproject.A
    • 听起来这仅适用于一级属性,但不适用于我正在使用的实际过滤器。
    • 你必须使用 createQuery 的 createAlias。我相应地编辑了答案。
    【解决方案3】:

    使用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"))
     );
    

    【讨论】:

    • 没有别名你会怎么做?
    • 在这种特定情况下,别名可能是不必要的。如果您要使用更深的路径,或者您的任何一对条件使用相同的基本路径(例如 b.foob.bar),它们是必要的
    • 这适用于一种情况;但在另一种情况下,我正在执行 Restrictions.sqlRestriction,它没有正确使用别名。知道如何使用它吗?
    • 我应该说,这是一个简化的例子,我的实际用例中每个过滤器都有几个嵌套级别的属性。抱歉,如果这是问题的根源
    • sqlRestriction 是否基于嵌套属性?自从我使用它已经有一段时间了,所以我不是 100% 确定这一点 - 但我认为 Hibernate 会保留你的别名,只要你为每个路径片段指定它们(例如,对于 ABCD,你会做 createAlias()对于A.B,然后是B_alias.CC_alias.D)。然后,您应该能够在 C_alias.D 上使用 ssqlRestriction(忽略文档中的“{alias}”位)。这对你不起作用吗?是否正在重新生成别名?
    猜你喜欢
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    相关资源
    最近更新 更多