2015-04-03 71 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

相關問題