使用三个OR谓词的多个连接的JPA Criteria查询

时间:2011-10-19 10:52:01

标签: jpa criteria-api

我正在使用JPA Criteria API编写一个查询,我希望所有旅行都匹配这些谓词:

  • 获取我拥有的所有旅行(MasterTravels)(所有者=用户)
  • 获取我作为乘客的所有旅行(乘客,用户=用户)
  • 获取我已申请的所有旅行(MasterTravelApplication,user = user)

第一个谓词很简单。我只是检查MasterTravel中的owner = user。对于第二个谓词,我需要加入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();

1 个答案:

答案 0 :(得分:2)

您没有描述实体之间的链接,但我猜想主旅行不一定至少有一个应用程序,并且因为您正在进行内部联接,所有没有的主旅行找不到任何申请。

使用以JoinType为参数的join方法,并使用JoinType.LEFT