Włączyłem logowanie SQL i sprawdziłem wyniki zapytania. W powyższym przypadku było to:
/* 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=?
Niezbędne połączenie jest już uwzględnione i wygląda wszystko, co byłoby potrzebne, to:
@Where(clause = "ppg_status <> 'D'")
Okazuje się jednak, że nie pracuj, ponieważ Hibernate dodaje zły alias tabeli:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Niestety po przypisaniu aliasu do tabeli nie można użyć oryginalnej nazwy tabeli — dlatego purchase_product_group.ppg_status <> 'D'
nie zadziała. I nie jestem świadomy sposobu na programowe określenie aliasu używanego przez Hibernate - więc obecnie wydaje się, że wybór dotyczy albo zakodowania na stałe nazwy aliasu, która jest używana przez Hibernate (tj. purchasepr1_.ppg_status <> 'D'
) lub użyć exists
metoda opisana w pytaniu.
AKTUALIZACJA: Po dalszym badaniu okazuje się, że zakodowanie nazw aliasów nie zawsze jest wykonalne. Oto zapytanie z kryteriami, w którym to nie zadziała:
/* 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=?
W końcu porzuciłem @Where
podejście i użyte @Filter
zamiast tego, co wydaje się znacznie lepsze, ponieważ może akceptować HQL zamiast nazw pól bazy danych, a po zastosowaniu na poziomie jednostki wpłynie na relacje (w przeciwieństwie do @Where
).