Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como adicionar uma cláusula where a uma entidade de tabela de junção explícita do Hibernate @OneToMany?


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 ).