私はこのようなことをしたい:
select count(*) from (select ...)
(SQLの場合と同じように)が、JPAの場合。
私がそれをどのように行うかについてのアイデアはありますか?
これでうまくいくはずです(JPA基準APIを使用したい場合):
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Long> query = cb.createQuery(Long.class);
Root<Entity> root = query.from(Entity.class);
//Selecting the count
query.select(cb.count(root));
//Create your search criteria
Criteria criteria = ...
//Adding search criteria
query.where(criteria);
Long count = getEntityManager().createQuery(query).getSingleResult();
一方、JP-QLを使用する場合は、次のコードでうまくいくはずです。
//Add the where condition to the end of the query
Query query = getEntityManager().createQuery("select count(*) from Entity entity where...")
Long count = query.getSingleResult();
私もこの問題に出くわしました。最終的には次のJPQLを実行したいと思います。
SELECT COUNT(u)
FROM (
SELECT DISTINCT u
FROM User u
JOIN u.roles r
WHERE r.id IN (1)
)
しかし、これは不可能であり、基準APIでも不可能でした。調査によると、これはJPAの設計上の制限にすぎません。 JPA仕様では、サブクエリはWHERE
句とHAVING
句でのみサポートされると規定されています(したがって、FROM
ではサポートされません)。
次のJPQL形式でクエリを書き換えます。
SELECT COUNT(u)
FROM User u
WHERE u IN (
SELECT DISTINCT u
FROM User u
JOIN u.roles r
WHERE r.id IN (1)
)
次のようにJPACriteriaAPIを使用します。
CriteriaQuery<Long> query = cb.createQuery(Long.class);
Root<User> u = query.from(User.class);
Subquery<User> subquery = query.subquery(User.class);
Root<User> u_ = subquery.from(User.class);
subquery.select(u_).distinct(true).where(u_.join("roles").get("id").in(Arrays.asList(1L)));
query.select(cb.count(u)).where(cb.in(u).value(subquery));
Long count = entityManager.createQuery(query).getSingleResult();
// ...
私の機能要件を解決しました。これにより、特定の機能要件を解決するための十分な洞察も得られます。