2011-10-19 12 views
2

私はすべての旅は、これらの述語のいずれかに一致する取得したいJPA基準のAPIを使用してクエリ書いている:すべての旅(MasterTravels)を取得JPA Critieraクエリは3を使用してOR述語結合が

  • をそのI最初

(所有者は=ユーザー)
  • 私は乗客(乗客、ユーザー=ユーザー)午前すべての旅
  • はすべて私が(MasterTravelApplication、ユーザー=ユーザー)に適用されていることを移動ゲットする独自の述語はeaですsy。私はMasterTravelでowner = userをチェックするだけです。 2番目の述語については、MasterTravel-> MTT-> Travel-> Passengerに参加して、Passenger_.user = userかどうかを確認する必要があります。 3番目の述語については、別の方向のMasterTravel-> MasterTravelApplicationに参加し、MasterTravelApplication_.user = userを確認する必要があります。これは私が2つの最初の作業を持っているので私のクエリを壊すものですが、私は最後の述語を追加しようとすると動作を停止します。

    最後の結合のために新しいルートを作成する必要がありますか、または以下の結合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

    関連する問題