在JPA 2.0 JPQL中,当一个人返回一个NEW对象时,如何使用FETCH JOINs? [英] In JPA 2.0 JPQL, when one returns a NEW object, how may one make use of FETCH JOINs?

查看:133
本文介绍了在JPA 2.0 JPQL中,当一个人返回一个NEW对象时,如何使用FETCH JOINs?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A colleague of mine has the following (apparently invalid) JPQL query:

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

(在此消息的后面)值得注意的是DonationAllocationCampaign实体的关系是多对一的,并标记为FetchType.LAZY.我的同事对此查询的意图是(除其他事项外)确保a.campaign被夸大"(急需获取).

It is worth noting (for later in this message) that DonationAllocation's relationship with a Campaign entity is many-to-one, and is marked as FetchType.LAZY. My colleague's intent with this query is to (among other things) ensure that a.campaign is "inflated" (eagerly fetched).

休眠(显然只是几个的一个JPA实现),面对此查询时,它说:

Hibernate (obviously just one JPA implementation of several), when faced with this query, says:

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节说:

This makes sense, as the select list contains only NEW DonationAllocationDTOEntity(), and section 4.4.5.3 of the JPA 2.0 specification says:

FETCH JOIN子句右侧引用的关联必须是从查询返回的实体或可嵌入对象引用的关联或元素集合.

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引用关联,因此该查询无效.

So since there is no "entity or embeddable that is returned as a result of the query" (it's a DTO constructed using the NEW operator), it follows that there is no possible association for a FETCH JOIN to reference, and hence this query is invalid.

在这种限制下,如何在这种情况下构造一个JPQL查询,以便迅速获取a.campaign(传递到构造函数表达式中)?

How, given this limitation, should one construct a JPQL query in this case such that a.campaign--passed into the constructor expression--is fetched eagerly?

推荐答案

我只需选择实体及其关联,然后对结果进行遍历以显式调用DTO构造函数.您将拥有编译时检查和可重构代码的其他优势:

I would simply select the entity and its association, and llopover the results to invoke the DTO constructor explicitely. You would have the additional advantage of compile-time checks and refactorable code:

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实体:

This query should also select what's needed, and avoid selecting the whole DonationAllocation entity:

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构造函数:

and you might just add the DTO constructor in the query if you want:

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加载实体.至少在我的测试中就是这样.

The fact the a.campaign is in the select clause should be sufficient to tell Hibernate to load the entity. At least that's how it behaves in my tests.

这篇关于在JPA 2.0 JPQL中,当一个人返回一个NEW对象时,如何使用FETCH JOINs?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆