JPA 2 CriteriaQuery, usando un límite

3 minutos de lectura

avatar de usuario
Menno

Estoy usando JPA 2. Por razones de seguridad, estoy trabajando de forma segura con CriteriaQuery (y, por lo tanto, no estoy buscando ninguna solución para las consultas escritas, etc.).

Recientemente me encontré con un problema en el que necesitaba establecer un SQL-LIMIT.

Después de mucho buscar, todavía no tuve éxito en encontrar una solución.

CriteriaQuery<Product> query = getEntityManager().getCriteriaBuilder().createQuery(Product.class);
Root<Product> product = query.from(Product.class);
query.select(product);

return em.createQuery(query).getResultList();

¿Alguien puede ayudarme?

avatar de usuario
Francisco Spaeth

Definir límite y compensar sobre el Consulta:

return em.createQuery(query)
         .setFirstResult(offset) // offset
         .setMaxResults(limit) // limit
         .getResultList();

De la documentación:

TypedQuery setFirstResult(int startPosition)

Establece la posición del primer resultado a recuperar. Parámetros:
Posición de salida – posición del primer resultado, numerado desde 0

TypedQuery setMaxResults(int maxResult)

Establezca el número máximo de resultados para recuperar.

  • Esto no aborda la pregunta original de cómo hacer esto con javax.persistence.criteria.CriteriaQuery. La solución aceptada utiliza la función ahora en desuso createCriteria().

    – Kenneth M. Kolano

    3 de marzo de 2018 a las 0:39

  • Es cierto que esta solución no soluciona el problema al usar JPA 2.

    – janeshs

    04/04/2018 a las 21:46


avatar de usuario
Kekzpanda

En aras de la exhaustividad, quiero responder a la pregunta inicial con respecto a la API de criterios de JPA.

Ante todo, puede aclarar por sí mismo de antemano cuándo usar JPQL y cuándo usar la API de criterios según el caso de uso. Hay un buen artículo sobre esto en el Documentación de ObjectDB sitio web que dice:

Una de las principales ventajas de utilizar la API de criterios es que los errores se pueden detectar antes, durante la compilación en lugar de durante el tiempo de ejecución. Por otro lado, para muchos desarrolladores, las consultas JPQL basadas en cadenas, que son muy similares a las consultas SQL, son más fáciles de usar y comprender.

Recomiendo este artículo en general porque describe de manera concisa cómo usar la API de criterios JPA. Hay un artículo similar sobre el API de consulta.

volver a la pregunta:

A CriteriaQuery ofrece un conjunto de restricciones a las que se puede acceder, por ejemplo, mediante el where() método. Como puede adivinar intuitivamente: no puede limitar la consulta a un número particular de resultados con tal restricción, excepto que tenga un caso trivial como limitar un identificador único (lo que haría obsoleto el uso de la API Criteria). Explicado de manera simple: un límite no es un criterio y, por lo tanto, no está cubierto por esa API. Ver también el viejo pero dorado Documentos de Java EE para más detalles.

Solución

Sin embargo, por supuesto, puede usar su objeto CriteriaQuery como base para una consulta JPQL. Entonces, primero, crea su CriteriaQuery tal como está:

CriteriaQuery<Product> criteriaQuery = 
    getEntityManager().getCriteriaBuilder().createQuery(Product.class);
Root<Product> product = criteriaQuery.from(Product.class);
criteriaQuery.select(product);

Luego usa el JPA Query constructor para CriteriaQuery objetos:

Query limitedCriteriaQuery = getEntityManager().createQuery(criteriaQuery)
     .setMaxResults(resultLimit); // this is the important part     
return limitedCriteriaQuery.getResultList();

Y así es básicamente cómo debe usar ambas API de acuerdo con la documentación y los artículos proporcionados.

  • Y ahí es donde también puede establecer el primer resultado. Útil para páginas.

    – Mariano LEANCE

    26 mayo 2020 a las 23:05

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad