Este artículo fue analizado por nuestros especialistas para garantizar la veracidad de nuestra esta reseña.
Solución:
En estas dos consultas, está utilizando JOIN para consultar a todos los empleados que tienen al menos un departamento asociado.
Pero, la diferencia es: en la primera consulta, solo devuelve los Empleados para Hibernate. En la segunda consulta, está devolviendo los Empleados y todos los departamentos asociados.
Entonces, si usa la segunda consulta, no necesitará hacer una nueva consulta para acceder a la base de datos nuevamente para ver los Departamentos de cada Empleado.
Puede utilizar la segunda consulta cuando esté seguro de que necesitará el Departamento de cada Empleado. Si no necesita el Departamento, utilice la primera consulta.
Recomiendo leer este enlace si necesita aplicar alguna condición WHERE (lo que probablemente necesitará): ¿Cómo expresar correctamente JPQL “join fetch” con la cláusula “where” como JPA 2 CriteriaQuery?
Actualizar
si no usas fetch
y los Departamentos siguen devolviéndose, se debe a que su asignación entre Empleado y Departamento (un @OneToMany
) se configuran con FetchType.EAGER
. En este caso, cualquier HQL (con fetch
o no) consultar con FROM Employee
traerá todos los departamentos. Recuerde que todos los mapeos *ToOne (@ManyToOne
y @OneToOne
) están ansiosos por defecto.
en este enlace que mencioné antes en el comentario, lea esta parte:
Una unión de “búsqueda” permite que las asociaciones o colecciones de valores se inicialicen junto con sus objetos principales mediante una sola selección. Esto es particularmente útil en el caso de una colección. Anula efectivamente la unión externa y las declaraciones perezosas del archivo de mapeo para asociaciones y colecciones.
este “JOIN FETCH” tendrá su efecto si tiene la propiedad (fetch = FetchType.LAZY) para una colección dentro de la entidad (ejemplo a continuación).
Y solo afecta el método de “cuándo debería ocurrir la consulta”. Y también debes saber esto:
hibernate tiene dos nociones ortogonales: cuándo se obtiene la asociación y cómo se obtiene. Es importante que no los confundas. Usamos fetch para ajustar el rendimiento. Podemos usar lazy para definir un contrato para qué datos están siempre disponibles en cualquier instancia separada de una clase en particular.
cuándo se obtiene la asociación –> su tipo “FETCH”
cómo se obtiene –> Unirse/seleccionar/Subseleccionar/Lote
En su caso, FETCH solo tendrá efecto si tiene departamento como un conjunto dentro de Empleado, algo como esto en la entidad:
@OneToMany(fetch = FetchType.LAZY)
private Set department;
cuando usas
FROM Employee emp
JOIN FETCH emp.department dep
conseguirás emp
y emp.dep
. cuando no usaste fetch todavía puedes obtener emp.dep
pero Hibernate procesará otra selección en la base de datos para obtener ese conjunto de departamentos.
por lo tanto, es solo una cuestión de ajuste del rendimiento, si desea obtener todos los resultados (lo necesita o no) en una sola consulta (búsqueda ansiosa), o si desea consultarlo más tarde cuando lo necesite (búsqueda perezosa).
Use la búsqueda ansiosa cuando necesite obtener datos pequeños con una selección (una consulta grande). O use la búsqueda diferida para consultar lo que necesita más tarde (muchas consultas más pequeñas).
usar buscar cuando:
-
no grande innecesario colección / conjunto dentro de esa entidad que está a punto de obtener
-
comunicación del servidor de aplicaciones al servidor de base de datos demasiado lejos y necesito mucho tiempo
-
es posible que necesite esa colección más tarde cuando no tenga acceso a ella (fuera de de El transaccional método/clase)
UNIRSE
Cuando usas JOIN
contra las asociaciones de una entidad, JPA generará un JOIN entre la entidad principal y las tablas de la entidad secundaria en la declaración SQL generada.
Entonces, tomando su ejemplo, al ejecutar esta consulta JPQL:
FROM Employee emp
JOIN emp.department dep
Hibernate va a generar la siguiente declaración SQL:
SELECT emp.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id
Tenga en cuenta que el SQL
SELECT
cláusula contiene sólo elemployee
columnas de la tabla, y no lasdepartment
unos. para buscar eldepartment
columnas de la tabla, necesitamos usarJOIN FETCH
en lugar deJOIN
.
UNIRSE A OBTENER
Entonces, en comparación con JOIN
los JOIN FETCH
le permite proyectar las columnas de la tabla de unión en el SELECT
cláusula de la instrucción SQL generada.
Entonces, en su ejemplo, al ejecutar esta consulta JPQL:
FROM Employee emp
JOIN FETCH emp.department dep
Hibernate va a generar la siguiente declaración SQL:
SELECT emp.*, dept.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id
Tenga en cuenta que, esta vez, el
department
las columnas de la tabla también se seleccionan, no solo las asociadas con la entidad enumerada en elFROM
Cláusula JPQL.
También, JOIN FETCH
es una gran manera de abordar la LazyInitializationException
cuando usa Hibernate, ya que puede inicializar asociaciones de entidades usando el FetchType.LAZY
estrategia de obtención junto con la entidad principal que está obteniendo.
Calificaciones y comentarios
Si haces scroll puedes encontrar las reseñas de otros administradores, tú también puedes mostrar el tuyo si te gusta.