Encendí el registro de SQL y examiné el resultado de la consulta. Para el caso anterior fue este:
/* 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=?
Así que la unión necesaria ya está incluida y parece como todo lo que se necesitaría es esto:
@Where(clause = "ppg_status <> 'D'")
Sin embargo, resulta que no funciona como Hibernate antepone el alias de tabla incorrecto:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Desafortunadamente, una vez que se asigna un alias a una tabla, no es posible usar el nombre de la tabla original, por lo que purchase_product_group.ppg_status <> 'D'
no funcionaría Y no conozco una forma de determinar el nombre de alias utilizado por Hibernate mediante programación, por lo que en la actualidad la elección parece ser codificar el nombre de alias que Hibernate utiliza (es decir, purchasepr1_.ppg_status <> 'D'
) o para usar exists
método descrito en la pregunta.
ACTUALIZACIÓN: En una investigación más profunda, resulta que codificar los nombres de los alias no siempre es factible. Aquí hay una consulta de criterios donde esto no funcionarí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=?
Al final abandoné el @Where
enfoque y usó @Filter
en cambio, lo que parece mucho mejor ya que puede aceptar HQL en lugar de nombres de campo de base de datos y cuando se aplica a nivel de entidad afectará las relaciones (a diferencia de @Where
).