我的同事具有以下(顯然無效)JPQL查詢:在JPA 2.0 JPQL中,當返回一個NEW對象時,如何使用FETCH JOIN?
SELECT NEW com.foobar.jpa.DonationAllocationDTOEntity(a.id, a.campaign, a.campAppeal, a.campDivision, a.divisionFund)
FROM DonationAllocation a JOIN a.donation d JOIN a.allocationType t
JOIN FETCH a.campaign
WHERE d.id = :donationId
AND (t.code = 'Pledge' OR t.code = 'MatchingPledge')
值得注意(供以後在該消息中),其DonationAllocation
的與Campaign
實體的關係是許多對一,並標記爲FetchType.LAZY
。我的同事對這個查詢的意圖是(除其他外)確保a.campaign
是「充氣」(急切地提取)。
休眠(顯然只是一個JPA實現的幾種),當面對這個查詢,說:
query specified join fetching, but the owner of the fetched association was not present in the select list
這是有道理的,因爲在選擇列表中只包含NEW DonationAllocationDTOEntity()
,並且部分JPA 2.0規範的4.4.5.3規定:
FETCH JOIN子句右側引用的關聯必須是從實體引用的關聯或元素集合,或者是作爲查詢結果返回的可嵌入元素。
所以,因爲沒有「被返回作爲所述查詢的結果實體或嵌入」(這是一個DTO使用NEW
操作者構造),接下去是沒有可能的關聯爲一個FETCH JOIN引用,因此這個查詢是無效的。
如何鑑於此限制,應該在這種情況下構建一個JPQL查詢,以便a.campaign
- 被分配到構造函數表達式中?
謝謝。 'DonationAllocation'目前是一個巨大的對象,與EAGER關係太多。我相信我的同事正在試圖撤回它的某些部分。只是碰巧他所做的其中一個關係實際上是希望在這個查詢中加載。有了這些新知識,這會改變你的答案嗎? –
是的,請參閱我的答案。但是如果加載實體就是這樣一個問題,那就意味着它的熱切關聯應該變得懶惰。我寧願讓一切都懶惰。 –