2015-04-03 67 views
3

我需要编写一个Criteria(或hql)来通过它的子实体的一个孩子的属性来查找父实体。这是我的实体:Hibernate Criteria:找到实体,如果它的任何一个孩子的孩子有一个特定的属性

// 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.. 
} 

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

如何为此编写一个hibernate标准?我现在写的所有内容如下:

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

然后我放弃了。

回答

6

试试这个

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"); 
+0

谢谢,这对我有用。我不确定它是否能正常工作,但至少它会返回一些结果:)我想我需要测试更多。 – sedran 2015-04-16 19:11:53

+0

如果没有找到与a.b相对应的对象或列表,那么甚至不会返回父对象。 – 2016-04-04 10:29:10

+1

@ZahidKhan您可以将['CriteriaSpecification.LEFT_JOIN'](https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/criterion/CriteriaSpecification.html#LEFT_JOIN)作为'createAlias中的第三个参数'方法。 – 2016-04-04 12:05:26

0

如果使用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一;”链接在你的B类中定义。

+0

我不能在B级添加一个字段。 – sedran 2015-04-16 19:12:25

相关问题