2016-03-16 49 views
1

這裏是我的模型:休眠排序實體<字符串,兒童>

@Entity 
@Table(name = "parent") 
public class Parent { 

    ... 

    @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REMOVE}, mappedBy = "parent") 
    @MapKeyColumn(name = "key") 
    private Map<String, Child> children; 

    ... 

} 

@Entity 
@Table(name = "child") 
public class Child { 

    ... 

    @Column(name = "key") 
    private String key; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "parent_id") 
    private Parent parent; 

    @Column(name = "property") 
    private String property; 

    ... 

} 

該映射是有用的,並適用於插入,更新,刪除的entites和選擇它們。

現在,我必須使用他們的子項屬性(取決於地圖鍵),像order by parent.children[<particular key>].property asc子句(我沒有在HQL中找到)那樣訂購父實體。我也不知道如何使用Criteria API來實現這一點。任何想法?

我現在唯一的解決方案是選擇由key篩選並按property排序的兒童,然後逐個Java代碼獲取父母,即使使用「獲取父母」設置也無效。

+0

我不知道它是否有效,但是您是否在'Parent.children'上嘗試了'@ OrderBy'註釋?它應該是'@OrderBy(「property asc」)'。 –

+0

註釋類型OrderBy:指定在檢索關聯或集合時集合值關聯或元素集合的元素排序。 似乎不是我的情況,因爲用於對映射集合中的項進行排序 – Aeteros

+0

由於'Map'沒有內在排序,我懷疑這是可以使用JPA的,因爲您不能指定Hibernate應該使用可排序的'Map'作爲實現。 – Smutje

回答

1

表創建報表出來是這樣的:

create table child (id bigint not null, key varchar(255), property varchar(255), parent_id bigint, primary key (id)) 
create table parent (id bigint not null, primary key (id)) 

與PARENT_ID約束父表。

向後合作,SQL似乎很直截了當:

select p.* from parent p join child c on p.id = c.parent_id where c.key = 'c1' order by c.property asc; 

這樣一來,JPQL和標準查詢也應該是直截了當:

List<Parent> po1 = em.createQuery("select p from Parent p join p.children c where c.key='c1' order by c.property asc", Parent.class).getResultList(); 
System.out.println(po1); 

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Parent> cq = cb.createQuery(Parent.class); 
Root<Parent> p = cq.from(Parent.class); 
Join<Parent, Child> c = p.join("children"); 
cq.select(p).where(cb.equal(c.get("key"), "c1")).orderBy(cb.asc(c.get("property"))); 
List<Parent> po3 = em.createQuery(cq).getResultList(); 
System.out.println(po3); 

父創建toString方法:

public String toString() { 
    return "Parent:"+id+":"+children; 
} 

and Child:

public String toString() { 
    return "Child:"+id+":"+key+":"+property; 
} 

這一點讓我下面的輸出:

Hibernate: select parent0_.id as id1_1_ from parent parent0_ inner join child children1_ on parent0_.id=children1_.parent_id where children1_.key='c1' order by children1_.property asc 
[Parent:4:{c1=Child:5:c1:0}, Parent:1:{c1=Child:2:c1:1}] 
Hibernate: select parent0_.id as id1_1_ from parent parent0_ inner join child children1_ on parent0_.id=children1_.parent_id where children1_.key=? order by children1_.property asc 
[Parent:4:{c1=Child:5:c1:0}, Parent:1:{c1=Child:2:c1:1}] 

這在我看來是由兒童財產,其中的關鍵是一定值下令父母。

+0

謝謝!似乎工作。 – Aeteros