Saltar al contenido

Hibernate HQL join fetch no recupera recursivamente

Después de de una prolongada selección de datos resolvimos esta incógnita que presentan muchos lectores. Te regalamos la respuesta y esperamos resultarte de gran apoyo.

Solución:

¡Las relaciones de Hibernate funcionan con diferentes estrategias de obtención…!

Hibernate proporciona 4 estrategias para recuperar datos:

SELECCIONE

@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id") 
@Fetch(FetchMode.SELECT)

En este método, se activan varios SQL. Este primero se dispara por recuperar todos los registros en la tabla principal. Los restantes se activan para recuperar registros para cada Registro principal. Este es básicamente el problema N+1. La primera consulta recupera N registros de la base de datos, en este caso, N registros principales. Para cada padre, una nueva consulta recupera el hijo. Por lo tanto, para N padres, N consultas recuperan información de la tabla secundaria.

UNIRSE

@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@Fetch(FetchMode.JOIN) 

Esto es similar a la estrategia de recuperación de SELECT, excepto por el hecho de que toda la recuperación de la base de datos se realiza por adelantado en la recuperación de JOIN, a diferencia de SELECT, donde ocurre según la necesidad. Esto puede convertirse en una consideración de rendimiento importante.

SUBSELECCIONAR

 @OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
 @Column(name="id")
 @Fetch(FetchMode.SUBSELECT)

Se disparan dos SQL. Uno para recuperar todos los padres y el segundo usa una consulta SUBSELECT en la cláusula WHERE para recuperar todos los hijos que tienen identificadores de padres coincidentes.

LOTE

@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@@BatchSize(size=2)

El tamaño del lote se asigna al número de padres cuyos hijos se recuperan. Entonces podemos especificar la cantidad de registros que se buscarán a la vez. ¡Pero se ejecutarán múltiples consultas!

Permite uno a muchos y muchos a muchos: unirse, seleccionar y subseleccionar

permite muchos a uno y uno a uno: unirse y seleccionar


Hibernate también distingue entre (cuándo se obtienen las asociaciones)

1.Obtención inmediata

una asociación, colección o attribute se recupera inmediatamente, cuando se carga el padre. (perezoso=“false”)

2.Obtención de colección perezosa

se recupera una colección cuando la aplicación invoca una operación sobre esa colección. (Este es el valor predeterminado para las colecciones.(lazy=“true”)

3″.Extra-perezoso“buscando colección –

se accede a los elementos individuales de la colección desde la base de datos según sea necesario. Hibernate intenta no recuperar toda la colección en la memoria a menos que sea absolutamente necesario (adecuado para colecciones muy grandes) (perezoso = “extra”)

4.Obtención de proxy

se obtiene una asociación de un solo valor cuando se invoca un método que no sea el captador de identificador sobre el objeto asociado. (perezoso = “apoderado”)

5″.Sin proxy“buscando –

se obtiene una asociación de un solo valor cuando se accede a la variable de instancia. En comparación con la obtención de proxy, este enfoque es menos perezoso.(lazy=“no-proxy”)

6.Perezoso attribute ir a buscar –

un attribute o se obtiene una asociación de un solo valor cuando se accede a la variable de instancia. (perezoso=“true”)

uno a muchos y muchos a muchos permite Inmediato, Layzy, Extra Lazy

muchos a uno y uno a uno permite proxy inmediato, sin proxy

Si sabe que solo tiene dos niveles en su árbol, ¿ha pensado en unir un nivel más profundo? ¿Algo como abajo?

SELECT DISTINCT domain FROM Domain domain 
  LEFT OUTER JOIN FETCH domain.operators operators1 
  LEFT OUTER JOIN FETCH domain.networkCodes 
  LEFT OUTER JOIN FETCH operators1.operators operators2 
  LEFT OUTER JOIN FETCH operators1.networkCodes
WHERE domain.domainId = :domainId

Marcaste tus asociaciones con EAGER. Entonces, haga lo que haga en su consulta, Hibernate cargará todos los dominios asociados y los códigos de red de los dominios cargados. Y cargará los dominios y códigos de red de los dominios adicionales, etc. etc. hasta que todas las cargas de colección devuelvan colecciones vacías o entidades que ya han sido cargadas.

Para evitar eso, haga que sus colecciones sean perezosas (como lo son por defecto). Luego, al cargar un dominio con sus operadores y sus códigos de red, se cargará exactamente eso.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *