2011-03-24 18 views

Respuesta

10

Esto debería hacer el truco (Si desea utilizar JPA criterios 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(); 

Por otro lado, si desea utilizar el documento JP-QL, el siguiente código debe hacer el truco:

//Add the where condition to the end of the query 
Query query = getEntityManager().createQuery("select count(*) from Entity entity where...") 
Long count = query.getSingleResult(); 
+1

El problema es que quería obtener el recuento de las filas devueltas de una subconsulta. Parece que no es posible porque las subconsultas no pueden usarse así en JPA –

+9

Esto no responde a la pregunta concreta en absoluto. El OP pregunta cómo contar los resultados de una subconsulta, no cómo contar los resultados de una consulta. – BalusC

22

Me encontré con este problema también. Me gusta en última instancia, para ejecutar el siguiente JPQL:

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

pero esto no fue posible, tampoco con los criterios del API. La investigación enseñó que esto era solo una limitación de diseño en JPA. La especificación JPA establece que las subconsultas solo se admiten en las cláusulas WHERE y HAVING (y por lo tanto no en el FROM).

Reescritura de la consulta en el siguiente formulario 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) 
) 

utilizando los criterios API JPA como los siguientes:

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

ha resuelto el requisito funcional para mí. Esto también debería brindarle suficiente información para resolver sus requisitos funcionales particulares.

+0

no puede usar este enfoque si desea contar el resultado de la consulta de agregación –

+0

@Martin ¿Qué enfoque sugeriría DISTINCTAR desde el CriteriaQuery arbitrario? – svlada

+0

@svlada, no encontré una solución efectiva, solo para devolver todas las filas y contarlas en el servidor de la aplicación. –

Cuestiones relacionadas