2010-07-19 4 views
3

Je voudrais convertir la requête SQL suivante:Comment spécifier plusieurs conditions sur la jointure gauche à l'aide de l'API JPA Criteria?

select * from region_tree country left outer join region_tree region 
on country.REG_CODE_PAR=region.REG_CODE 
and region.LFT < country.LFT 
and region.RGT > country.RGT 
and region.REG_CODE_PAR = 'ALL' 
and COUNTRY.STATUS_CODE = 'A' 
and REGION.STATUS_CODE = 'A 

en requête basée JPA Crtieria.

J'ai créé une entité pour représenter l'auto rejoindre:

@Entity 
@Table(name = "REGION_TREE") 
public class RegionTree implements Serializable { 
    ... some other attributes 

    @ManyToOne 
    @JoinColumn(name = "REG_CODE_PAR") 
    private RegionTree region; 

    ... getters and setters 
} 

J'ai utilisé le code suivant pour créer la requête JPA

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<RegionTree> cq = cb.createQuery(RegionTree.class); 
Root<RegionTree> e = cq.from(RegionTree.class); 
Join<RegionTree, RegionTree> r = e.join("region", JoinType.LEFT); 
Predicate p1 = cb.greaterThan(e.get("lft").as(Integer.class), r.get("lft").as(Integer.class)); 
Predicate p2 = cb.lessThan(e.get("rgt").as(Integer.class), r.get("rgt").as(Integer.class)); 
Predicate p3 = cb.equal(e.get("statusCode"), "A"); 
Predicate p4 = cb.equal(r.get("statusCode"), "A"); 
Predicate p5 = cb.equal(r.get("regCodePar"), "ALL"); 
cq.where(p1,p2,p3,p4,p5); 
TypedQuery<RegionTree> tq = em.createQuery(cq); 
l = tq.getResultList();` 

C'est la requête générée automatiquement par Hibernate quand je lance ce morceau de code.

select 
regiontree0_.REG_CODE as REG1_7_, 
regiontree0_.LFT as LFT7_, 
regiontree0_.NAME as NAME7_, 
regiontree0_.REG_CODE_PAR as REG4_7_, 
regiontree0_.RGT as RGT7_, 
regiontree0_.STATUS_CODE as STATUS6_7_ 
from 
REGION_TREE regiontree0_ 
left outer join 
REGION_TREE regiontree1_ 
on regiontree0_.REG_CODE_PAR=regiontree1_.REG_CODE 
where 
cast(regiontree0_.LFT as integer)>cast(regiontree1_.LFT as integer) 
and cast(regiontree0_.RGT as integer)<cast(regiontree1_.RGT as integer) 
and regiontree0_.STATUS_CODE=? 
and regiontree1_.STATUS_CODE=? 
and regiontree1_.REG_CODE_PAR=? 

J'ai essayé plusieurs façons, notamment la suppression de la ligne de code cq.where mais la requête générée ne peut pas correspondre à mon original. Ai-je configuré quelque chose de mal?

+0

Apparemment, JPA 2.0 ne prend pas en charge les conditions ON supplémentaires. Il est prévu pour 2.1. Vous pouvez le faire en utilisant directement l'API d'Hibernate. – Thilo

Répondre

1

Essayez d'appeler cq.select(r); après avoir créé une jointure. Sans cq.select(), le résultat du dernier appel cq.from() est utilisé comme racine de sélection.

Questions connexes