Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment ajouter une clause where à une entité de table de jointure explicite Hibernate @OneToMany ?

J'ai activé la journalisation SQL et examiné le résultat de la requête. Pour le cas ci-dessus, c'était ceci :

/* 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=?

Ainsi, la jointure nécessaire est déjà incluse et elle semble comme tout ce qu'il faudrait, c'est ceci :

@Where(clause = "ppg_status <> 'D'")

Cependant, il s'avère que non fonctionne comme Hibernate ajoute le mauvais alias de table :

where
    (
        purchasepr0_.ppg_status <> 'D'
    )
    and purchasepr0_.crd_id=?

Malheureusement, une fois qu'un alias est attribué à une table, il n'est pas possible d'utiliser le nom de la table d'origine - donc purchase_product_group.ppg_status <> 'D' ne fonctionnerait pas. Et je ne suis pas au courant d'un moyen de déterminer le nom d'alias utilisé par Hibernate par programmation - donc à l'heure actuelle, le choix semble être soit de coder en dur le nom d'alias utilisé par Hibernate (c'est-à-dire purchasepr1_.ppg_status <> 'D' ) ou d'utiliser le exists méthode décrite dans la question.

MISE À JOUR : Après une enquête plus approfondie, il s'avère que le codage en dur des noms d'alias n'est pas toujours réalisable. Voici une requête de critères où cela ne fonctionnerait pas :

/* 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=?

Au final j'ai abandonné le @Where approche et utilisé @Filter à la place, ce qui semble bien mieux car il peut accepter HQL plutôt que les noms de champs de base de données et lorsqu'il est appliqué au niveau de l'entité affectera les relations (contrairement à @Where ).