Zapnul jsem protokolování SQL a prozkoumal výstup dotazu. Ve výše uvedeném případě to bylo toto:
/* 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=?
Takže potřebné spojení je již zahrnuto a vypadá jako vše, co by bylo potřeba, je toto:
@Where(clause = "ppg_status <> 'D'")
Ukazuje se však, že není work as Hibernate předpíše nesprávný alias tabulky:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Bohužel, jakmile je k tabulce přiřazen alias, není možné použít původní název tabulky – takže purchase_product_group.ppg_status <> 'D'
by nefungovalo. A nevím o způsobu, jak programově určit název aliasu, který Hibernate používá – takže v současnosti se zdá, že je na výběr buď napevno zakódovat název aliasu, o kterém se zjistilo, že ho používá Hibernate (tj. purchasepr1_.ppg_status <> 'D'
) nebo použijte exists
metoda popsaná v otázce.
AKTUALIZACE: Při dalším zkoumání se ukazuje, že pevné kódování jmen aliasů není vždy funkční. Zde je dotaz na kritéria, kde by to nefungovalo:
/* 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=?
Nakonec jsem opustil @Where
přistoupil a použil @Filter
místo toho se zdá mnohem lepší, protože může přijímat HQL spíše než názvy databázových polí a při použití na úrovni entity ovlivní vztahy (na rozdíl od @Where
).