16

私はこのようなことをしたい:

select count(*) from (select ...)

(SQL の場合と同様)、ただし JPA では。

私がそれを行う方法についてのアイデアはありますか?

4

3 に答える 3

32

私もこの問題に出くわしました。最終的には、次の JPQL を実行したいと思います。

SELECT COUNT(u)
FROM (
   SELECT DISTINCT u
   FROM User u
   JOIN u.roles r
   WHERE r.id IN (1)
)

しかし、これは不可能であり、基準 API を使用しても不可能でした。調査によると、これは JPA の設計上の制限に過ぎないことがわかりました。JPA 仕様では、サブクエリはWHEREandHAVING句でのみサポートされている (したがって ではサポートされていない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)
)

次のように JPA Criteria API を使用します。

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();
// ...

私の機能要件を解決しました。これにより、特定の機能要件を解決するための十分な洞察が得られるはずです。

于 2012-08-22T15:32:26.050 に答える
7

これでうまくいくはずです(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();
于 2011-03-26T16:10:47.503 に答える