Ativei o log do SQL e examinei a saída da consulta. Para o caso acima foi assim:
/* 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=?
Portanto, a junção necessária já está incluída e parece como tudo o que seria necessário é isso:
@Where(clause = "ppg_status <> 'D'")
No entanto, acontece que não trabalhar como Hibernate precede o alias de tabela errado:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Infelizmente, uma vez que um alias é atribuído a uma tabela, não é possível usar o nome original da tabela - então
purchase_product_group.ppg_status <> 'D'
não funcionaria. E eu não estou ciente de uma maneira de determinar o nome do alias usado pelo Hibernate programaticamente - então, no momento, a escolha parece ser codificar o nome do alias que é encontrado para ser usado pelo Hibernate (ou seja, purchasepr1_.ppg_status <> 'D'
) ou usar o exists
método descrito na pergunta. ATUALIZAÇÃO: Em uma investigação mais aprofundada, verifica-se que codificar os nomes de alias nem sempre é viável. Aqui está uma consulta de critérios em que isso não funcionaria:
/* 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=?
No final, abandonei o
@Where
abordagem e usou @Filter
em vez disso, o que parece muito melhor, pois pode aceitar HQL em vez de nomes de campos de banco de dados e, quando aplicado no nível da entidade, afetará os relacionamentos (ao contrário de @Where
).