gpt4 book ai didi

jpa - 在 JPA 2.0 JPQL 中,当返回一个 NEW 对象时,如何使用 FETCH JOIN?

转载 作者:行者123 更新时间:2023-12-04 21:21:42 25 4
gpt4 key购买 nike

我的一位同事有以下(显然无效)JPQL 查询:

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是“膨胀的”(急切地获取)。

Hibernate(显然只是几个 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 节说:

The association referenced by the right side of the FETCH JOIN clause must be an association or element collection that is referenced from an entity or embeddable that is returned as a result of the query.



因此,由于没有“作为查询结果返回的实体或可嵌入的”(它是使用 NEW 运算符构造的 DTO),因此没有可能的 FETCH JOIN 关联关联,因此这查询无效。

鉴于此限制,在这种情况下应该如何构建 JPQL 查询,使得 a.campaign --传递到构造函数表达式中--是否急切地获取?

最佳答案

我会简单地选择实体及其关联,然后将结果 llopover 以显式调用 DTO 构造函数。您将获得编译时检查和可重构代码的额外优势:

select a 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')

...

for (DonationAllocation a : list) {
result.add(new DonationAllocationDTOEntity(a.id,
a.campaign,
a.campAppeal,
a.campDivision,
a.divisionFund));
}

编辑:

此查询还应选择需要的内容,并避免选择整个 DonationAllocation 实体:
select a.id, a.campaign, a.campAppeal, a.campDivision, a.divisionFund
from DonationAllocation a
JOIN a.donation d
JOIN a.allocationType t
WHERE d.id = :donationId
AND (t.code = 'Pledge' OR t.code = 'MatchingPledge')

如果需要,您可以在查询中添加 DTO 构造函数:
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
WHERE d.id = :donationId
AND (t.code = 'Pledge' OR t.code = 'MatchingPledge')

a.campaign 在 select 子句中的事实应该足以告诉 Hibernate 加载实体。至少这就是它在我的测试中的表现。

关于jpa - 在 JPA 2.0 JPQL 中,当返回一个 NEW 对象时,如何使用 FETCH JOIN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11164496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com