0

メインクエリと、カテゴリの ID を持つサブクエリを一致させる必要があります。JPA Criteria Query では、クエリが types を返すため、Predicate を Category に設定できませんPubThread

Predicate correlatePredicate = criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), rootPubThread);

基準クエリ全体の下。

   CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
   CriteriaQuery<PubThread> cq = criteriaBuilder.createQuery(PubThread.class);

    // 1) MainQuery
    // Create the FROM
    Root<PubThread> rootPubThread = cq.from(PubThread.class);
    // Create the JOIN from the first select: join-chaining. You only need the return for ordering. e.g. cq.orderBy(cb.asc(categoryJoin.get(Pub_.title)));
    Join<Pub, PubCategory> categoryJoin = rootPubThread.join(PubThread_.pups).join(Pub_.pubCategory);
    // Create the WHERE
    cq.where(criteriaBuilder.not(criteriaBuilder.equal(rootPubThread.get(PubThread_.id), threadId)));
    // Create the SELECT, at last
    cq.select(rootPubThread).distinct(true);

    // 2) Subquery
    Subquery<PubThread> subquery = cq.subquery(PubThread.class); 
    Root<PubThread> rootPubThreadSub = subquery.from(PubThread.class); 
    subquery.where(criteriaBuilder.equal(rootPubThread.get(PubThread_.id), threadId));
    Join<Pub, PubCategory> categoryJoinSub = rootPubThreadSub.join(PubThread_.pups).join(Pub_.pubCategory);
    subquery.select(rootPubThreadSub);

    Predicate correlatePredicate = criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), rootPubThread);
    subquery.where(correlatePredicate);
    cq.where(criteriaBuilder.exists(subquery));

この SQL コードに一致するように、この条件クエリをどのように作成しますか? 私はかなり近いと思います。

SELECT Distinct(pt2.id), pt2.name
FROM pubthread pt2
JOIN pub_pubthread ppt2 ON pt2.id = ppt2.pubThreads_id
JOIN pub p2 ON ppt2.pups_id = p2.id
JOIN pubcategory pc2 ON p2.pubCategoryId = pc2.id
WHERE pt2.id != 1 and EXISTS (
    SELECT DISTINCT(pt.id) FROM pubthread pt
    JOIN pub_pubthread ppt ON pt.id = ppt.pubThreads_id
    JOIN pub p ON ppt.pups_id = p.id
    JOIN pubcategory pc ON p.pubCategoryId = pc.id
    where pc2.id = pc.id and pt.id = 1
)
4

1 に答える 1

0

述語に間違ったオブジェクトを割り当てました。サブクエリの ID を親 ID に一致させたい場合、述語がルートに属していない場合Joinは、 ではなくを割り当てる必要があります。Rootまあ、それはどれほど明白です。:)しかし、喜んで共有します。以下は新しいクエリです。Predicate一番下に追加があり、問題を解決します。また、別のブール ステートメントと組み合わせて使用​​します。

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery mainQuery = criteriaBuilder .createQuery(PubThread.class);

// 1) MainQuery
// Create the FROM
Root<PubThread> rootPubThread = mainQuery.from(PubThread.class);
// Create the JOIN from the first select: join-chaining. You only need the return for ordering. e.g. cq.orderBy(cb.asc(categoryJoin.get(Pub_.title)));
Join<Pub, PubCategory> categoryJoin = rootPubThread.join(PubThread_.pups).join(Pub_.pubCategory);
// Create the WHERE
mainQuery.where(criteriaBuilder.not(criteriaBuilder.equal(rootPubThread.get(PubThread_.id), threadId)));
// Create the SELECT, at last
mainQuery.select(rootPubThread).distinct(true);

// 2) Subquery
Subquery<PubThread> subquery = mainQuery.subquery(PubThread.class); 
Root<PubThread> rootPubThreadSub = subquery.from(PubThread.class); 
//subquery.where(criteriaBuilder.equal(rootPubThread.get(PubThread_.id), threadId));
Join<Pub, PubCategory> categoryJoinSub = rootPubThreadSub.join(PubThread_.pups).join(Pub_.pubCategory);
subquery.select(rootPubThreadSub);

//Predicate correlatePredicate = criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), rootPubThread);
Predicate correlatePredicate = criteriaBuilder.and(
        //criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), rootPubThread),
        criteriaBuilder.equal(categoryJoinSub.get(PubCategory_.id), categoryJoin.get(PubCategory_.id)),

        criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), threadId)
        );
subquery.where(correlatePredicate);     

//Predicate correlatePredicate = criteriaBuilder.equal(rootPubThreadSub.get(PubThread_.id), rootPubThread);
Predicate mainPredicate = criteriaBuilder.and(
        criteriaBuilder.not(criteriaBuilder.equal(rootPubThread.get(PubThread_.id), threadId)),
        criteriaBuilder.exists(subquery)
        );
//cq.where(criteriaBuilder.exists(subquery));
mainQuery.where(mainPredicate);


TypedQuery<PubThread> typedQuery = em.createQuery(mainQuery);
List<PubThread> otherPubThreads = typedQuery.getResultList();
于 2013-09-06T10:42:02.787 に答える