Ik zette SQL-logboekregistratie aan en onderzocht de uitvoer van de query. Voor het bovenstaande geval was het dit:
/* 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=?
Dus de benodigde join is al inbegrepen en het ziet er uit zoals het enige dat nodig zou zijn, is dit:
@Where(clause = "ppg_status <> 'D'")
Het blijkt echter dat niet werk terwijl de slaapstand de verkeerde tabelalias voorvoegt:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Wanneer een alias eenmaal aan een tabel is toegewezen, is het helaas niet mogelijk om de originele tabelnaam te gebruiken - dus purchase_product_group.ppg_status <> 'D'
zou niet werken. En ik ben niet op de hoogte van een manier om de aliasnaam die door Hibernate wordt gebruikt programmatisch te bepalen - dus op dit moment lijkt de keuze te zijn om ofwel de aliasnaam die wordt gebruikt door Hibernate hard te coderen (d.w.z. purchasepr1_.ppg_status <> 'D'
) of om de exists
. te gebruiken methode beschreven in de vraag.
UPDATE: Bij nader onderzoek blijkt dat het hard coderen van de aliasnamen niet altijd werkbaar is. Hier is een criteriumquery waar dit niet zou werken:
/* 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=?
Uiteindelijk heb ik de @Where
. opgegeven aanpak en gebruikt @Filter
in plaats daarvan, wat veel beter lijkt omdat het HQL kan accepteren in plaats van databaseveldnamen en wanneer toegepast op entiteitsniveau relaties zal beïnvloeden (in tegenstelling tot @Where
).