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 SÍ se recupera la información del otro extremo de la asociación con una ÚNICA CONSULTA.