2014-10-29 25 views
0

我想對使用與另一個實體的連接的實體運行條件查詢。但從Java/Hibernate的角度來看,沒有提到這個第二個實體,從第二個實體到第一個實體只有一個。使用hibernate條件查詢加入一個沒有直接引用的實體

爲了使它可以理解的,這裏是cat'ifized情況:

===== Cat.java ===== 
@Id private long id; 

@Column(unique = true, nullable = false) 
private String name; 

===== Kitten.java ===== 
@Id private long id; 

@Column(unique = true, nullable = false) 
private String name; 

@OneToOne(optional = false) 
private Cat mother;   //only one child per mother ... 

現在我想查詢貓有限制和排序依據的小貓。

session.createCriteria(Cat.class) 
    .createAlias(???? , "kitten") 
    .add(Restrictions.like("kitten.name", "name_of_a_kitten") 
    .addOrder(Order.asc("kitten.name")) 
    .list(); 

首先我想用的子查詢,但我無法找到訂購和subquerys不如在我眼裏別名爲可讀的解決方案。

貓不能改變,所以沒有辦法改變雙向方向性。

我該如何完成查詢?

Btw。我正在使用hibernate 4.2。

回答

0

我認爲不可能通過簡單的hibernate標準查詢來實現您的需求。

Criteria API只能「選擇」根實體,並且需要Cat作爲根實體。不幸的是,Cat實體沒有提及Kitten,所以不可能加入它。

從我的角度來看,你只有兩種選擇:

1)HQL

,如果你不固定到標準的API,只需使用HQL。

final List<Cat> cats = session.createQuery("select c from Kitten k join k.mother c where k.name=:name order by k.name") 
    .setParameter("name", "name_of_a_kitten").list(); 

2)從收集小貓提取貓明確

選擇小貓至收集

final List<Kitten> kittens = session.createCriteria(Kitten.class) 
        .add(Restrictions.like("name", "name_of_a_kitten")) 
        .addOrder(Order.asc("name")) 
        .list(); 

和變換,以貓的收集,例如使用lambda-J(OnToOne關係不是懶惰,所以貓被加載)

final List<Cat> cats = extract(kittens, on(Kitten.class).getMother()); 

子查詢

正如您所指出的那樣,使用子查詢,因爲不可能通過小貓訂貨的沒有用屬性

final DetachedCriteria q = DetachedCriteria.forClass(Kitten.class) 
      .createAlias("mother", "c") 
      .add(Restrictions.like("name", "name_of_a_kitten")) 
      .setProjection(Projections.property("c.id")); 

    final List<Cat> cats = session.createCriteria(Cat.class) 
      .add(Property.forName("id").in(q)).list(); //not possible order by Kitten attributes 
相關問題