2016-08-30 8 views
3

私はJPA 2.1クライテリアAPIで、このSQLクエリを記述したいと思います:内部クエリの外部クエリのメンバを参照する方法は?

select * from t_question q 
where 
(select count(*) from t_question_tag tag 
    where 
     q.question_id = tag.question_id 
     AND tag.tag_id in (18, 1) 
) = 2; 

私は内側のクエリで外側質問メンバーを参照する方法を見つけ出すことはできません。

私はこの時点で、現在のよ:

 CriteriaQuery<Question> cq = criteriaBuilder.createQuery(Question.class); 
Root<Question> questions = cq.from(Question.class); 
cq.distinct(true); 

    Subquery<Long> selectTags = cq.subquery(Long.class); 
    Root<QuestionTag> qt = selectTags.from(QuestionTag.class); 
    Join<QuestionTag, Question> qtJoin = qt.join("question"); 
    selectTags 
    .select(criteriaBuilder.count(qtJoin)) 
    .where(
     qt.get("tag").in(filter.getTags()) 
     ); 
    cq.where(criteriaBuilder.and(insArray), 
     criteriaBuilder.equal(criteriaBuilder.literal(filter.getTags().size()), selectTags)); 

しかし、それは、第二の参加が作成されます。 SQLの結果は次のとおりです。

SELECT DISTINCT ... 
FROM T_QUESTION question0_ 
WHERE 1     = 
    (SELECT COUNT(question3_.question_id) 
    FROM T_QUESTION_TAG questionta2_ 
    INNER JOIN T_QUESTION question3_ 
    ON questionta2_.question_id=question3_.question_id 
    WHERE questionta2_.tag_id IN (18)); 
+0

2番目のコードフラグメントでは、 'cq'は何を表していますか? (それに応じてコード部分を更新してください) – Riduidel

+0

そして、私はJPAがその点でどのように動作しているのか正確にはわかりませんが、あなたの 'WHERE ... = 2'は' WHERE 1 = ... ' – Riduidel

答えて

1

私は、サブクエリがよりこの

Subquery<Long> selectTags = cq.subquery(Long.class); 
Root<QuestionTag> qt = selectTags.from(QuestionTag.class); 
selectTags.select(criteriaBuilder.count(qt)); 
selectTags.where(
     criteriaBuilder.equal(questions.get("id"), qt.get("id")), 
     qt.get("tag").in(filter.getTags()) 
     ); 

外部クエリを参照するために、外側のクエリ(「質問」)から候補者を使用し、ドンのようなことを期待したいです以前に参加した理由は分かりません。私は、 "Question"と "Tag"のフィールドが両方とも "id"と呼ばれると仮定しました。

関連する問題