2010-07-19 55 views
3

我想下面的SQL查詢轉換:如何使用JPA Criteria API在左連接中指定多個條件?

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 

到基於JPA Crtieria查詢。

我創建以表示自實體加入:

@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 
} 

我用下面的代碼來創建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();` 

這是當運行此由Hibernate自動生成的查詢一段代碼。

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

我已經嘗試了多種方法,包括去除cq.where行代碼,但生成的查詢無法比擬的我原來的一個。我配置了什麼錯?

+0

顯然,JPA 2.0不支持額外的ON條件。計劃爲2.1。你可以直接使用Hibernate的API來完成。 – Thilo 2013-11-01 08:59:11

回答

1

嘗試在創建連接後調用cq.select(r);。如果沒有cq.select(),最後的cq.from()調用的結果將用作選擇根。