2010-03-01 28 views
53

我最近了解到,有可能在JPQL語句來創建新的對象如下:JPQL在Select語句中創建新對象 - 避免還是擁抱?

select new Family(mother, mate, offspr) 
from DomesticCat as mother 
    join mother.mate as mate 
    left join mother.kittens as offspr 

這是不是要避免或者說擁抱?根據良好實踐,何時使用此功能是合理的?

回答

91

不要回避,因爲在§10.2.7.2中提到了它,所以存在完全有效的用例。 JPQL構造函數表達式在SELECT子句中EJB 3.0 JPA Specification

構造函數可以在 選擇列表中用於返回一個或多個Java 實例。指定的類不是 需要成爲實體或將 映射到數據庫。 構造函數名稱 必須完全合格 。

如果指定一個實體類的名字在SELECT NEW子句中 的 導致實體實例在 新的狀態。

SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) 
FROM Customer c JOIN c.orders o 
WHERE o.count > 100 

總之,使用SELECT NEW當你不想要檢索一個完整的實體或對象的類型安全方式進行全面的圖(而不是一個Object[])。無論您將查詢的結果映射到實體類還是非映射類都將取決於您的選擇。一個典型的例子是一個列表屏幕(你可能不需要所有的細節)。

換句話說,不要在任何地方使用它,但不要禁止使用它(很少有東西只是黑色或白色)。

+0

我想做同樣的事情,但在我的查詢中,我有一些聯合抓取和jpa抱怨:查詢指定聯接抓取,但抓取關聯的所有者不在選擇列表中。悲傷... – 2012-03-19 13:49:19

+1

請編輯你的答案,並使「構造函數名稱必須完全合格」粗體..這是非常重要的和一個常見的錯誤來源。 – 2012-04-18 15:31:35

+1

答案完全正確,但鏈接的文檔與答案不符。它應該是http://jcp.org/aboutJava/communityprocess/final/jsr317/index。html – Pumuckline 2012-05-22 16:35:40

24

當您想檢索數據傳輸對象時,您經常使用此類查詢。也許報告可以成爲使用它的好地方。如果您只想要檢索單個域對象(而不是家庭中的),那麼沒有理由使用它。

+3

提及DTO的+1 - 正好我的使用案例 – 2010-07-01 08:06:11

+1

好點,但你認爲存儲庫應該返回DTOs而不是實體?我正在轉換服務層中的對象,在Repository中是不是太早? – Mejmo 2015-07-03 14:27:59

5

用new創建的對象不一定是DTO,即將由Business層導出的對象。它也可以是POJO域對象,即業務層內部使用的對象。

使用這種POJO作爲部分對象而不是完整的JPA實體的原因是在特定種類的JOINS中的性能。一個很好的資源解釋這是:http://use-the-index-luke.com/sql/join/hash-join-partial-objects

相關問題