1

型付きクエリを作成したい。

TypedQuery<PubThread> query = em.createQuery(queryString, PubThread.class);
query.setParameter("threadId", threadId);
List<PubThread> otherPubThreads = query.getResultList();

queryString には次の SQL があります (現在、param および static 選択値はありません)。

SELECT pt2 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  
)

String を単純な select: に制限すると、うまくいきますSELECT Distinct(pt2.id), pt2.name FROM pubthread pt2。JOIN 行を追加するとすぐに文句を言うでしょう。JPAでJOINSを使用して適切にクエリを実行するにはどうすればよいですか? エラーは次のとおりです。 org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ON near line 1, column 81 [SELECT pt2 FROM com.brayan.webapp.model.PubThread pt2 JOIN pub_pubthread ppt2 ON pt2.id = ppt2.pubThreads_id ]

間違いなく、条件クエリの方が優れています。私はそれを解決空間の一部として受け入れます。

4

2 に答える 2

2

とった。以下の結合の完全な例を参照してください。以下で構成されています。

  • 複数の結合 (結合連鎖)
  • サブクエリ
  • ルート テーブル以外の結合テーブルに対する述語相関/方程式。

また、他の人が間違ったアプローチを確認するために、廃止されたコード行にコメントしました。

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);
于 2013-09-06T13:49:55.113 に答える
1

呼び出すcreateQueryときは、HQL を記述する必要がありますが、SQL を記述する必要はありません (あなたqueryStringは ではありませんHQL)。
HQL では、マッピング エンティティに従ってオブジェクトを結合する必要があります。
SQLクエリが必要な場合は、createNativeQueryメソッドを使用してください。HQL クエリの作成方法に関するドキュメント
を参照してください。

于 2013-09-05T14:36:24.010 に答える