2011-10-19 32 views
2

我正在寫使用JPA標準API查詢,我想所有的旅行匹配任何這些謂詞的:JPA條件而定的查詢與很多連接使用三個或謂詞

  • 獲取所有的旅行(MasterTravels),我自己(所有者=用戶)
  • 找我的乘客(客運,用戶=用戶)
  • 獲取所有旅行,我已申請(MasterTravelApplication,用戶=用戶)

第一要緊的旅行謂詞是ea SY。我只是檢查是否owner =用戶在MasterTravel。對於第二個謂詞,我需要加入MasterTravel-> MTT-> Travel-> Passenger,然後檢查Passenger_.user = user。對於第三個謂詞,我需要加入另一個方向MasterTravel-> MasterTravelApplication並檢查MasterTravelApplication_.user = user。這是什麼打破了我的查詢,因爲我有兩個第一次工作,但當我嘗試添加最後一個謂詞停止工作。

我應該爲最後一個連接創建一個新的根,或者如何獲取下面的連接1和連接2的聯合?

CriteriaQuery<MasterTravel> q = cb.createQuery(MasterTravel.class); 
Root<MasterTravel> root = q.from(MasterTravel.class); 

// Joins 1, these works fine 
Join<MasterTravel, MTT> mtts = root.join(MasterTravel_.mtt); 
Join<MTT, Travel> travels = mtts.join(MTT_.travel); 
Join<Travel, Passenger> passengers = travels.join(Travel_.passengers);      

// Joins 2, this doesn't work 
Join<MasterTravel, MasterTravelApplication> application = root.join(MasterTravel_.applications); 

Predicate p = cb.or(
    cb.equal(passengers.get(Passenger_.user), user), 
    cb.equal(root.get(MasterTravel_.owner), user), 
    cb.equal(application.get(MasterTravelApplication_.user), user)); // When I add this it stops working 

q.select(root); 
q.where(p);   
q.orderBy(cb.desc(root.get(MasterTravel_.createdTimestamp)));      
q.distinct(true); 

List<MasterTravel> resultList = em.createQuery(q).getResultList(); 

回答

2

你不描述實體之間的聯繫,但我猜想,主遊不一定至少有一個應用程序,因爲你正在做內部聯接,所有主是傳播沒有找到任何應​​用程序。

使用以JoinType作爲參數的連接方法,並使用JoinType.LEFT

+0

是的,對不起。我忘了提及MasterTravelApplication在MasterTravel中被映射爲@OneToMany。用左連接而不是內連接,它的工作非常好,謝謝! – Jonas

+0

@Jonas如果這是解決方案。你可以分享你做了什麼嗎? – feder