¿Qué es y qué hace JPA Entity Graph?

| Última modificación: 15 de octubre de 2024 | Tiempo de Lectura: 3 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

Si usas Java Persistence API de seguro te has tenido que enfrentar en las consultas con el famoso problema de la n+1 queries. JPA Entity Graph es una herramienta que nos permite definir cuáles son las entidades y relaciones que queremos cargar en nuestras consultas. El día de hoy te explicaremos en qué consiste JPA Entity Graph y cómo hacer uso de esta herramienta.

JPA Entity Graph
Imagen: Medium

¿Qué es JPA Entity Graph?

JPA Entity Graph es una característica introducida en JPA 2.1 que nos permite definir de forma explícita qué atributos o relaciones de una entidad se deben cargar cuando realizamos una consulta. Funciona agrupando un conjunto de atributos que quieres obtener de una entidad y sus relaciones y te permite evitar cargar datos innecesarios que no vas a utilizar en un momento específico.

A diferencia de las estrategias tradicionales de carga, como lo son FetchType.LAZY y FetchType.EAGER, que son estáticas, los Entity Graphs te permiten decidir qué atributos cargar en tiempo de ejecución. Si estás haciendo algún procesamiento con entidades con relaciones complejas, como @OneToMany o @ManyToOne, que pueden generar muchas consultas adicionales, deberías plantearte el usar JPA Entity Graphs.

Problema de las n+1 Queries

El problema de las n+1 queries ocurre cuando una consulta inicial genera muchas consultas adicionales para cargar entidades relacionadas de manera perezosa (esto es denominado lazy loading ). Hagamos de cuenta que tienes una entidad Experto que tiene varias Imparticiones. Al obtener una lista de expertos, cada vez que accedes a las imparticiones de un experto, se ejecuta una consulta adicional, lo que aumenta exponencialmente el número total de consultas. JPA Entity Graph te permite realizar un join que cargue todas las entidades relacionadas de una sola vez.

¿Cómo funciona JPA Entity Graph?

Un JPA Entity Graph te permite especificar, a través de anotaciones o programación, qué relaciones y atributos quieres cargar de una entidad. Hay dos formas principales de definir un Entity Graph: usando anotaciones o mediante la API de JPA.

Definir un JPA Entity Graph con anotaciones

Una forma de crear un JPA Entity Graph es a través de la anotación @NamedEntityGraph, que puedes aplicar en una entidad. Veamos cómo:

@Entity
@NamedEntityGraph(
name = "ExpertoConImparticiones",
attributeNodes = @NamedAttributeNode("imparticiones")
)
public class Experto {
// Código de la clase Experto
}

En este caso hemos definido un JPA Entity Graph llamado ExpertoConImparticiones, que indica que cuando carguemos un experto, también queremos cargar sus imparticiones.

Definir un JPA Entity Graph de forma programática

Otra manera de definir un Entity Graph es hacerlo de manera programática, usando la API de JPA. Esto te da mayor flexibilidad para crear gráficos en tiempo de ejecución:

EntityGraph<Experto> entityGraph = entityManager.createEntityGraph(Experto.class);
entityGraph.addAttributeNodes("imparticiones");

Con esta aproximación, puedes crear dinámicamente el gráfico de atributos que quieres cargar.

¿Cómo utilizar JPA Entity Graph en consultas?

Una vez que tienes definido el Entity Graph, puedes usarlo en tus consultas de JPA para asegurarte de que las entidades relacionadas se carguen correctamente:

Usar JPA Entity Graph en una consulta JPQL

Supongamos que queremos obtener todos los expertos y sus imparticiones usando un Entity Graph. Podemos hacerlo así:

TypedQuery<Experto> consulta = em.createQuery("SELECT e FROM Experto e", Experto.class);
consulta.setHint("javax.persistence.loadgraph", em.getEntityGraph("ExpertoConImparticiones"));
List<Experto> expertos = consulta.getResultList();

En este ejemplo, estamos utilizando el gráfico de entidades ExpertoConImparticiones para cargar tanto los expertos como sus imparticiones en una sola consulta. Esto evita el problema de las n+1 queries.

Diferencia entre fetchgraph y loadgraph

Cuando usas JPA Entity Graph, puedes decidir si quieres utilizar fetchgraph o loadgraph, dos propiedades que determinan cómo se deben cargar los datos.

  • fetchgraph: Solo cargará los atributos definidos en el Entity Graph y nada más.
  • loadgraph: Cargará los atributos definidos en el Entity Graph, pero también incluirá los que estén configurados como EAGER en la entidad.

Dependiendo de tus necesidades, puedes elegir una u otra. Si solo quieres cargar lo necesario y nada más, fetchgraph es la opción adecuada.

Si quieres seguir aprendiendo más sobre todas las herramientas Java y sobre este popular lenguaje, únete a nuestro bootcamp java, en donde podrás adquirir toda la fundamentación necesaria para incursionar en el mercado laboral. ¡Anímate a dar el primer paso en el camino de tus sueños!

Ramón Maldonado

Full Stack Developer y Responsable de Formación base en KeepCoding.

Posts más leídos

¡CONVOCATORIA ABIERTA!

Java y Spring Boot

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado