JPA e Hibernate: criterios frente a JPQL o HQL
¿ Cuáles son las ventajas y desventajas de utilizar Criteria o HQL ? La API de Criteria es una buena forma orientada a objetos de expresar consultas en Hibernate, pero a veces las consultas de Criteria son más difíciles de entender/construir que HQL.
¿Cuándo utilizas Criteria y cuándo HQL? ¿Qué prefieres en qué casos de uso? ¿O es sólo cuestión de gustos?
Prefiero principalmente las consultas de criterios para consultas dinámicas. Por ejemplo, es mucho más fácil agregar algunos pedidos dinámicamente o dejar algunas partes (por ejemplo, restricciones) dependiendo de algún parámetro.
Por otro lado, estoy usando HQL para consultas estáticas y complejas, porque es mucho más fácil de entender/leer HQL. Además, creo que HQL es un poco más potente, por ejemplo, para diferentes tipos de unión.
Existe una diferencia en términos de rendimiento entre HQL y criteriosQuery: cada vez que activa una consulta utilizando criteriosQuery, se crea un nuevo alias para el nombre de la tabla que no se refleja en el último caché consultado para ninguna base de datos. Esto genera una sobrecarga al compilar el SQL generado, lo que lleva más tiempo de ejecución.
Respecto a las estrategias de recuperación [http://www.hibernate.org/315.html]
- Criteria respeta la configuración de pereza en tus asignaciones y garantiza que lo que deseas cargar se cargue. Esto significa que una consulta de Criterios puede dar como resultado varias declaraciones SELECT inmediatas de SQL para recuperar el subgrafo con todas las asociaciones y colecciones asignadas no diferidas. Si desea cambiar el "cómo" e incluso el "qué", utilice setFetchMode() para habilitar o deshabilitar la búsqueda de combinaciones externas para una colección o asociación en particular. Las consultas de criterios también respetan completamente la estrategia de recuperación (unir, seleccionar, subseleccionar).
- HQL respeta la configuración de pereza en sus asignaciones y garantiza que se cargue lo que desea cargar. Esto significa que una consulta HQL puede dar como resultado varias declaraciones SELECT inmediatas de SQL para recuperar el subgrafo con todas las asociaciones y colecciones asignadas no diferidas. Si desea cambiar el "cómo" e incluso el "qué", use LEFT JOIN FETCH para habilitar la recuperación de combinaciones externas para una colección en particular o una asociación anulable de muchos a uno o uno a uno, o JOIN FETCH para habilitar Búsqueda de combinación interna para una asociación de muchos a uno o uno a uno que no admite valores NULL. Las consultas HQL no respetan ningún fetch="join" definido en el documento de mapeo.
Criteria es una API orientada a objetos, mientras que HQL significa concatenación de cadenas. Eso significa que se aplican todos los beneficios de la orientación a objetos:
- En igualdad de condiciones, la versión OO es algo menos propensa a errores. Cualquier cadena antigua podría agregarse a la consulta HQL, mientras que solo los objetos de Criterios válidos pueden incluirse en un árbol de Criterios. Efectivamente, las clases de Criterios están más restringidas.
- Con la función de autocompletar, el OO es más reconocible (y por lo tanto más fácil de usar, al menos para mí). No es necesario recordar qué partes de la consulta van y dónde; el IDE puede ayudarte
- Tampoco es necesario recordar los detalles de la sintaxis (como qué símbolos van y dónde). Todo lo que necesitas saber es cómo llamar a métodos y crear objetos.
Dado que HQL es muy parecido a SQL (que la mayoría de los desarrolladores ya conocen muy bien), estos argumentos de "no es necesario recordar" no tienen tanto peso. Si HQL fuera más diferente, entonces esto sería más importante.