Hibernate: Recuperación de objetos. Fetch y Lazy

Abr 24, 2014 | TIC-tek

Hibernate recupera la información de la base de datos de una forma peculiar.

Existen dos conceptos importantes que debemos controlar cuando se trabaja con Hibernate:

  • Cuándo decide Hibernate recuperar la información de la base de datos y cargarla en memoria.
  • De qué forma se trae la información de la base de datos, es decir, qué sentencias SQL utiliza para recuperar la información.

Cuando Hibernate accede a una entidad que se relaciona con otras mediante asociaciones ¿cómo recupera la información?

Criteria consulta = session.createCriteria(Empresa.class);
List empresas = consulta.list();

Recupera todas empresas, pero, ¿también recupera todos los empleados asociados a la empresa?

Modo Lazy

Hibernate, por defecto, maneja las asociaciones de la siguiente manera:

  • Recupera los objetos Empresa.
  • Sólo cuando de forma programática se accede a los objetos de la asociación, Hibernate recupera los objetos Empleado de la base de datos.

Este comportamiento viene configurado por un parámetro llamado lazy que por defecto está a false. Hibernate tiene un  comportamiento perezoso por defecto.

Define cuándo se recupera la información de la asociación.

Este modo se puede parametrizar mediante los siguientes valores:

  • true.
  • false.
  • extra.
Modo Fetch

 Define cómo se recupera la información de la base de datos.

El parámetro fetch configura este comportamiento. Toma dos valores:

  • select: valor por defecto.
  • join.
  • subjoin.

Ejemplo

Entidad Empresa:

...
<hibernate-mapping package="modelo">
<class name="Empresa" table="empresa" >
<id name="id" column="idEmpresa" type="long">
<generator class="increment"></generator>
</id>
...
<set name="empleados">
<key column="idEmpresa"></key>
<one-to-many class="Empleado"/>
</set>
</class>
</hibernate-mapping>

Entidad Empleado:

...
<hibernate-mapping package="modelo">
<class name="Empleado" table="empleado" >
<id name="id" column="idEmpleado" type="long">
<generator class="increment"></generator>
</id>
<property name="nombre" column="nombre" type="string" />
<property name="sueldo" column="sueldo" type="double" />
</class>
</hibernate-mapping>

Código Java:

Criteria consulta = sesion.createCriteria(Empresa.class);
List lista = consulta.list();
...

Se lanza SÓLO una select para Empresa, es decir, Hibernate NO carga en memoria los objetos de tipo Empleado inicialmente.

SÓLO cuando Hibernate detecta que se va a acceder a la información de Empleados se generan las correspondientes select.

...
for (int i = 0; i < lista.size(); i++) {
Empresa e = (Empresa)lista.get(i);
Set<Empleado> empleados = e.getEmpleados();
Iterator<Empleado> it = empleados.iterator();
while (it.hasNext()) {
Empleado empleado = (Empleado) it.next();
}
}
...

Esto ocurre porque con la configuración que se ha definido inicialmente se está trabajando con:

  • ” fetch=”select”.
  • ” lazy=”true”.

Se pasa a modificar a continuación la configuración del problema para comprobar su comportamiento.

Entidad Empresa -Modificación 1-

...
<hibernate-mapping package="modelo">
<class name="Empresa" table="empresa" >
<id name="id" column="idEmpresa" type="long">
<generator class="increment"></generator>
</id>
...
<set name="empleados" fetch="select" lazy="false">
<key column="idEmpresa"></key>
<one-to-many/>
</set>
</class>
</hibernate-mapping>

Código -Modificación 1-

 ...
Criteria consulta = sesion.createCriteria(Empresa.class);
List lista = consulta.list();
...

Se lanza una select para Empresa y otras select para recuperar todos los empleados, es decir, en este caso SÍ se recupera la información del otro extremo de la asociación.

Entidad Empresa -Modificación 2-

...
<hibernate-mapping package="modelo">
<class name="Empresa" table="empresa" >
<id name="id" column="idEmpresa" type="long">
<generator class="increment"></generator>
</id>
...
<set name="empleados" fetch="join”>
<key column="idEmpresa"></key>
<one-to-many/>
</set>
</class>
</hibernate-mapping>

Código -Modificación 2-

 ...
Criteria consulta = sesion.createCriteria(Empresa.class);
List lista = consulta.list();
...

Se lanza SÓLO select para recuperar Empresas y empleados, es decir, en este caso  se recupera la información del otro extremo de la asociación con una ÚNICA CONSULTA.

Catálogo 2024

Conoce nuestra oferta formativa para este año

Catálogo IA

Descarga nuestro catálogo específico de Inteligencia Artificial

Últimas entradas