【问题标题】:Hibernate Criteria: find entity if any of its children's children have a specific propertyHibernate Criteria:如果它的任何孩子的孩子具有特定属性,则查找实体
【发布时间】:2015-06-08 18:48:59
【问题描述】:

我需要编写一个 Criteria(或 hql)来通过其子实体的子实体的属性来查找父实体。这是我的实体:

// The top level parent class
public class A {
    private Long id;
    private String someProperty;
    private B b;
    // and some other attributes...
}

// The second level parent class :)
public class B {
    private Long id;
    private List<C> cList;
    // and some other attributes...
}

public class C {
    private Long id;
    private B b;
    private List<D> dList;
    // Other attributes..
}

public class D {
    private Long id;
    private C c;
    private String importantAttribute;
    // Other attributes..
}

问题如下。如果任何 D 记录具有条件 importantAttribute=="something" 并且如果 A 具有条件 someProperty=="somethingelse",我想获取 A 记录的列表。

如何为此编写休眠条件?到目前为止,我只能写以下内容:

Criteria criteria = getSession().createCriteria(A.class, "a");
criteria.add(Restrictions.eq("a.someProperty", "somethingelse");

DetachedCriteria sub = DetachedCriteria.forClass(D.class, "d");
sub.add(Restrictions.eq("d.importantAttribute", "something"));
sub.setProjection(Projections.property("id"));

然后我放弃了。

【问题讨论】:

    标签: java hibernate hql criteria


    【解决方案1】:

    如果使用 HQL,应该可以这样:

      TypedQuery<A> query = em
                .createQuery(
                        "SELECT a FROM D d join fetch d.c c join fetch c.b b join fetch b.a a where a.someProperty = :someProperty and d. importantAttribute = :importantAttribute",
                        A.class);
        query.setParameter("someProperty", "somethingelse");
        query.setParameter("importantAttribute", "something");
        List<A> results = query.getResultList();
    

    你需要有一个“私人 A a;”在 B 类中定义的链接。

    【讨论】:

    • 我无法在B类中添加字段。
    【解决方案2】:

    试试这个

    Criteria criteria = getSession().createCriteria(A.class, "a");
    criteria.createAlias("a.b", "b");
    criteria.createAlias("b.cList", "c");
    criteria.createAlias("c.dList", "d");
    criteria.add(Restrictions.eq("a.someProperty", "somethingelse");
    criteria.add(Restrictions.eq("d.importantAttribute", "something");
    

    【讨论】:

    • 谢谢,这对我有用。我不确定它是否正常工作,但至少它会返回一些结果 :) 我认为我需要进行更多测试。
    • 如果没有找到针对 a.b 的对象或列表怎么办,那么它甚至不会返回父对象。
    • @ZahidKhan 您可以将CriteriaSpecification.LEFT_JOIN 作为createAlias 方法中的第三个参数传递。
    • @PredragMaric 方法已弃用 cr.createAlias("a.b", "ab", CriteriaSpecification.LEFT_JOIN);休眠 4.1。
    • @ZahidKhan 你是对的,但是有一种替代方法。使用cr.createAlias("a.b", "ab", JoinType.LEFT_OUTER_JOIN)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 2014-09-20
    相关资源
    最近更新 更多