5

JPA 2 Criteria APIを使用して次のクエリのいずれかを実行することはどういうわけか可能ですか?基本的に、プロファイルで使用されるテンプレートは多数あります。システム内の各ユーザーには、任意の数のプロファイルと2つのアクティブなプロファイルがあります。すべてのテンプレートと、それを使用するアクティブなプロファイルを所有しているユーザーの数を取得したいと思います。

代替案1

SELECT t.id, count(p.id)
FROM template t
LEFT JOIN profile p ON p.template_id = t.id
LEFT JOIN users u ON (u.active_profile_id = p.id OR u.active_personal_profile_id = p.id)
GROUP BY t.id

代替案2

SELECT t.id, count(p.id)
FROM COMPETENCE.template t
LEFT JOIN COMPETENCE.profile p ON (p.template_id = t.id)
LEFT JOIN users u1 on u1.active_profile_id = p.id
LEFT JOIN users u2 on u2.active_personal_profile_id = p.id
GROUP BY t.id

すべてのテンプレートを取得するための要件をスキップした場合、ルートとしてユーザーとプロファイルを使用するだけで、次のようになります。

CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<User> from = cq.from(User.class);
Root<Profile> from2 = cq.from(Profile.class);
Join<Profile, Template> join = from2.join(Profile_.template);
cq.where(cb.or(
             cb.equal(from.get(User_.activeCompetenceProfile), from2),
             cb.equal(from.get(User_.activePersonalProfile), from2)
));
cq.groupBy(join.get(Template_.id));
cq.multiselect(join.get(Template_.id), cb.count(from2.get(Profile_.id)));
List<Tuple> tuples = em.createQuery(cq).getResultList();

しかし、すべてのテンプレートを取得するには、WHERE句を使用できないと思いますが、最初のクエリと同様に外部結合が必要です。ただし、結合に特定のON句を設定できないため、代替1は不可能と思われ、ユーザーとテンプレートの両方が同時にルートである必要があるため、代替2は不可能と思われます。すべてのテンプレートを取得するには、テンプレートをルートとして使用し、プロファイルと結合する必要があります。これはうまくいきますが、ONパラメータがプロファイルではなくユーザーに保存されているため、プロファイルをユーザーと結合できません。私の知る限り、2番目のテーブルに格納されているパラメータでテーブルを別のテーブルと結合することはできません。

もちろん、このタスクは、すべてのテンプレートを選択して2番目のクエリを実行し、それを最初のクエリの結果とマージするなど、回りくどい方法で解決できますが、1つのクエリで実行できる場合は、よりクリーンなコードが作成されます。

4

0 に答える 0