Включих SQL регистриране и прегледах изхода на заявката. За горния случай беше следното:
/* load one-to-many com.prepaytec.pacasso.common.model.Card.purchaseProductGroups */
select
* /* the actual field list has been omitted for brevity */
from
pacasso.purchaseprodgrp_card purchasepr0_
inner join
pacasso.purchase_product_group purchasepr1_
on purchasepr0_.ppg_id=purchasepr1_.ppg_id
where
(
exists (
select
*
from
purchase_product_group ppg
where
ppg.ppg_id = purchasepr0_.ppg_id
AND ppg.ppg_status <> 'D'
)
)
and purchasepr0_.crd_id=?
Така че необходимото присъединяване вече е включено и изглежда като всичко, което би било необходимо, е това:
@Where(clause = "ppg_status <> 'D'")
Оказва се обаче, че не са работи като Hibernate предварява грешния псевдоним на таблицата:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
За съжаление, след като псевдоним е присвоен на таблица, не е възможно да се използва оригиналното име на таблицата - така че purchase_product_group.ppg_status <> 'D'
нямаше да работи. И не знам за начин за програмно определяне на псевдонима, използван от Hibernate - така че в момента изборът изглежда е или твърд код на псевдонима, за който е установено, че се използва от Hibernate (т.е. purchasepr1_.ppg_status <> 'D'
) или да използвате exists
метод, описан във въпроса.
АКТУАЛИЗАЦИЯ: При по-нататъшно разследване се оказва, че твърдото кодиране на имената на псевдонимите не винаги е работещо. Ето запитване за критерии, при което това няма да работи:
/* criteria query */
select
* /* the actual field list has been omitted for brevity */
from
pacasso.merchant_acquirer this_
left outer join
pacasso.purchaseprod_merchant_acquirer purchasepr2_
on this_.mac_id=purchasepr2_.mac_id
and (
// This wouldn't work with any alias since the required
// table is pacasso.purchase_product purchasepr3_, which
// is joined below.
purchasepr2_.ppr_status <> 'D'
)
left outer join
pacasso.purchase_product purchasepr3_
on purchasepr2_.ppr_id=purchasepr3_.ppr_id
where
this_.mac_code=?
and this_.cst_id=?
В крайна сметка изоставих @Where
подход и използва @Filter
вместо това, което изглежда много по-добре, тъй като може да приема HQL вместо имена на полета на базата данни и когато се прилага на ниво обект, ще засегне връзките (за разлика от @Where
).