Hibernate
Tutorial Hibernate: Optimización de asociaciones con carga lazy
Hibernate lazy: carga diferida. Aprende a implementar la carga diferida en Hibernate con ejemplos prácticos y detallados.
Aprende Hibernate GRATIS y certifícateIntroducción
La optimización de asociaciones con carga lazy en Hibernate es una práctica común para mejorar el rendimiento de las consultas a la base de datos al cargar entidades relacionadas solo cuando sea necesario.
La carga perezosa (lazy loading) retrasa la recuperación de datos relacionados hasta el momento en que realmente se necesitan, lo que puede reducir la sobrecarga de la base de datos y mejorar el rendimiento de la aplicación.
FetchType.LAZY
Considera un ejemplo de una relación many-to-one entre dos entidades: Book
y Author
.
Cada libro está asociado a un único autor. En este caso, podríamos querer cargar los detalles del autor solo cuando sea necesario, en lugar de cargarlos automáticamente cada vez que recuperamos un libro de la base de datos.
Primero, definimos nuestras entidades Book
y Author
con la anotación @ManyToOne
en la entidad Book
para representar la relación con Author
. Luego, configuramos la carga perezosa en la asociación usando la anotación @ManyToOne(fetch = FetchType.LAZY)
.
package com.example.model;
import jakarta.persistence.*;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY) // Por defecto es EAGER
private Author author;
// Getters and setters
}
package com.example.model;
import jakarta.persistence.*;
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and setters
}
En este ejemplo, la asociación entre Book
y Author
se carga perezosamente, lo que significa que cuando recuperamos un objeto Book
de la base de datos, el objeto Author
asociado no se cargará automáticamente.
En cambio, Hibernate generará una consulta separada para cargar los detalles del autor solo cuando se acceda explícitamente a la propiedad author
de un objeto Book
.
package com.example.service;
import com.example.model.Book;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class BookService {
@PersistenceContext
private EntityManager entityManager;
public Book findBookById(Long id) {
return entityManager.find(Book.class, id);
}
}
En el servicio BookService
, cuando recuperamos un libro por su identificador utilizando el método findBookById
, Hibernate solo recuperará los detalles del libro y no cargará automáticamente el autor asociado.
Sin embargo, si posteriormente accedemos a la propiedad author
del libro recuperado, Hibernate generará una consulta adicional para cargar los detalles del autor.
Book book = bookService.findBookById(1L);
// Hasta este punto, solo se ha cargado el libro, no el autor.
Author author = book.getAuthor(); // Hibernate generará una consulta para cargar el autor.
Esto permite que la carga de datos se optimice para minimizar la sobrecarga en la base de datos y mejorar el rendimiento de la aplicación, ya que solo se recuperan los datos relacionados cuando realmente se necesitan.
El FetchType.LAZY
puede aplicarse a todos los tipos de asociaciones en Hibernate, incluyendo @OneToOne
, @OneToMany
, @ManyToOne
, y @ManyToMany
.
Atributos básicos
Los atributos básicos también pueden configurarse para cargarse de manera perezosa utilizando la anotación @Basic
con un modo de carga lazy. Esto es útil para atributos grandes que no se necesitan siempre, como blobs o textos largos.
import jakarta.persistence.*;
@Entity
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic(fetch = FetchType.LAZY)
private byte[] fileContent;
// Getters and setters
}
La anotación @Basic(fetch = FetchType.LAZY)
indica que el contenido del archivo representado por byte[] fileContent
no se cargará automáticamente cuando la entidad a la que pertenece sea recuperada de la base de datos. En cambio, fileContent
solo se cargará en la memoria cuando el código acceda específicamente a este campo.
@LazyCollection
Hibernate también ofrece la anotación @LazyCollection
que puede ser usada en colecciones para especificar explícitamente la estrategia de carga lazy, independientemente de las configuraciones globales.
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import jakarta.persistence.*;
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "author")
@LazyCollection(LazyCollectionOption.TRUE)
private Set<Book> books;
// Getters and setters
}
La anotación @OneToMany(mappedBy = "author")
establece una relación de uno a muchos entre Author
y Book
, indicando que un autor puede tener múltiples libros.
Sin embargo, la adición de @LazyCollection(LazyCollectionOption.TRUE)
modifica el comportamiento de carga predeterminado de esta colección. En lugar de cargar todos los libros asociados a un autor tan pronto como se recupera el autor de la base de datos (comportamiento de carga eager por defecto en algunas configuraciones de @OneToMany
), la opción LazyCollectionOption.TRUE
asegura que los libros solo se cargarán cuando se acceda explícitamente a la colección books
.
La distinción entre usar @OneToMany(fetch = FetchType.LAZY)
y @LazyCollection(LazyCollectionOption.TRUE)
en Hibernate se centra en cómo gestionan la carga perezosa de colecciones. @OneToMany(fetch = FetchType.LAZY)
es una parte estándar de JPA que utiliza proxies para diferir la carga de las colecciones hasta que son accedidas, ofreciendo así compatibilidad entre diferentes implementaciones de JPA.
Por otro lado, @LazyCollection(LazyCollectionOption.TRUE)
es exclusivo de Hibernate y proporciona un control más preciso sobre la carga de colecciones, evitando en algunos casos el uso de proxies, lo que resulta útil en situaciones donde los proxies presentan limitaciones o complicaciones.
Básicamente, ambas permiten carga lazy, pero mientras @OneToMany
con FetchType.LAZY
asegura la portabilidad, @LazyCollection
ofrece opciones más específicas y adaptadas para optimizar el rendimiento dentro del ecosistema de Hibernate.
Ejercicios de esta lección Optimización de asociaciones con carga lazy
Evalúa tus conocimientos de esta lección Optimización de asociaciones con carga lazy con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Consultas JPQL avanzadas
Configuración con JPA
Tipos de datos personalizados
Consultas Criteria avanzadas
Operaciones en cascada
Anotaciones JPA
Asociación Many To One
Funciones en consultas JPQL
Asociación Many To Many entre Actor y Pelicula
Asociación One To Many entre Curso y Estudiante
Tipos de datos básicos
Consultas Criteria básicas
Asociación Many To Many
CRUD de entidades con asociaciones
Optimización de asociaciones con carga lazy
Asociación One To Many
Configuración con Maven
Asociación One To One
CRUD en Hibernate
Operaciones en cascada
Introducción a Hibernate
Atributos de tipo enum en entidades JPA
Carga de asociaciones en consultas con EntityGraph
Configuración con Gradle
Asociación One To One entre Libro y Resumen
Asociación One To Many
Asociación Many To Many
Creación de entidades
Ciclo de vida de una entidad
Consultas JPQL básicas
Carga de asociaciones en consultas con EntityGraph y anotaciones
Tipos de datos embebidos
Asociación Many To One entre Paciente y Clinica
Asociación Many To One
Optimización de consultas con DTOs
Atributos @Transient en entidades
Asociación One To One
Todas las lecciones de Hibernate
Accede a todas las lecciones de Hibernate y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Hibernate
Introducción Y Entorno
Configuración Hibernate Con Gradle
Introducción Y Entorno
Configuración Hibernate Con Maven
Introducción Y Entorno
Configuración Hibernate Con Jpa
Introducción Y Entorno
Creación De Entidades Jpa
Entidades Jpa Y Tipos De Datos
Tipos De Datos En Hibernate
Entidades Jpa Y Tipos De Datos
Atributos @Transient En Entidades
Entidades Jpa Y Tipos De Datos
Enums En Hibernate
Entidades Jpa Y Tipos De Datos
Tipos De Datos Embebidos
Entidades Jpa Y Tipos De Datos
Crud En Hibernate
Entidades Jpa Y Tipos De Datos
Ciclo De Vida De Una Entidad
Entidades Jpa Y Tipos De Datos
Asociación One To One
Asociaciones Entre Entidades
Asociación One To Many
Asociaciones Entre Entidades
Asociación Many To One
Asociaciones Entre Entidades
Asociación Many To Many
Asociaciones Entre Entidades
Operaciones En Cascada
Asociaciones Entre Entidades
Consultas Jpql Básicas
Consultas Hql Y Jpql
Consultas Jpql Avanzadas
Consultas Hql Y Jpql
Funciones En Consultas Jpql
Consultas Hql Y Jpql
Consultas Criteria Básicas
Api Criteria De Jpa
Consultas Criteria Avanzadas
Api Criteria De Jpa
Carga De Asociaciones En Consultas Con Entitygraph
Api Entitygraph
Carga De Asociaciones En Consultas Con Entitygraph Y Anotaciones
Api Entitygraph
Optimización De Consultas Con Dtos
Optimización
Optimización De Asociaciones Con Carga Lazy
Optimización
Certificados de superación de Hibernate
Supera todos los ejercicios de programación del curso de Hibernate y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el concepto de carga lazy y su impacto en el rendimiento de las aplicaciones.
- Aprender a implementar carga lazy en relaciones y para atributos básicos utilizando anotaciones específicas en Hibernate.
- Entender el uso de
@LazyCollection
para especificar la estrategia de carga lazy en colecciones.