2012-01-18 38 views
1

我有一個對象包含一個列表作爲其字段的對象,該對象映射到數據庫。 我想創建一個查詢,將從對象和前面提到的列表中選擇幾個字段。從JPA中的對象中選擇一個列表

的對象映射:

@Entity 
@Table(name="buys") 
@PrimaryKeyJoinColumn(name="buy_id") 
public class Buy extends DomainObject implements Serializable { 

     @Column(name = "buy_name") 
     private String buyName; 

     @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
     @JoinColumn(name="buy_id", referencedColumnName = "buy_id") 
     private List<InsersionOrder> insertionOrders; 

     //other fields omitted 

} 

我使用的查詢:

"select new com.dtos.domainObjects.BuyDTO(b.id, b.buyName, b.insertionOrders) from Buy b where b.buyGroupId = :groupId and b.isDeleted = false" 

當運行此查詢冬眠(我的JPA供應商)產生一個錯誤的查詢:

Hibernate: select buy0_.buy_id as col_0_0_, buy0_.buy_name as col_1_0_, . as col_2_0_ from buys buy0_ inner join domain_objects buy0_1_ on buy0_.buy_id=buy0_1_.id inner join insertion_orders insertiono1_ on buy0_.buy_id=insertiono1_.buy_id inner join domain_objects insertiono1_1_ on insertiono1_.io_id=insertiono1_1_.id where buy0_.buy_group_id=? and buy0_1_.is_deleted=0 

InsertionOrder字段也從DomainObject繼承。

如果我省略了列表並且只從Buy對象(即id,name)中選擇「簡單」字段,查詢就可以正常工作。

我錯過了什麼?

謝謝。

回答

3

此語法從結果集的每行中創建一個BuyDTO實例。即使它有效,它也不會返回你想要返回的東西。集合字段可能不是HQL查詢的select子句的一部分。

第一個解決方案:不要返回一個DTO,返回實體本身。

解決方法二:選擇實體,並建立自己的DTO實例:

select b from Buy b 
left join fetch b.insertionOrders i 
where b.buyGroupId = :groupId and b.isDeleted = false 

for (Buy b : list) { 
    dtoList.add(new BuyDTO(b.getId(), b.getBuyName(), b.getInsertionOrders()); 
} 

解決方案三:選擇你想要什麼,並自己組裝的DTO:

select b.id, b.buyName, i 
from Buy b 
left join b.insertionOrders i 
where b.buyGroupId = :groupId and b.isDeleted = false 

在每一行結果是,您將找到一個ID,一個buyName和一個insertionOrder。因此,您必須在第一次遇到新ID時創建一個DTO,然後將該訂單添加到已經構建的DTO中,以滿足此ID的下一個時間。

+0

爲什麼一個集合不能成爲select子句的一部分?我發現在你的第三個例子中,你選擇了集合 – 2012-01-18 14:10:04

+1

因爲它沒有什麼意義,Hibernate會知道結果集的哪些行應該組合在一起作爲同一個列表的一部分。我沒有找到HQL的任何參考,但JPA2規範在第160頁說:*「請注意,必須指定SELECT子句以僅返回單值表達式。因此下面的查詢 無效: SELECT o .lineItems FROM Order AS o'* – 2012-01-18 14:24:24

+0

>'Hibernate會知道結果集的哪些行應該組合在一起作爲同一個列表的一部分。「 - 我不太確定。如果Hibernate足夠聰明地加入每個實體的ID,它應該知道如何將整個結果集分組到單獨的列表中。畢竟,這也是手冊代碼所做的。 – 2014-01-05 23:46:35

相關問題