¿Te gustaría aprender Java Empresarial desde cero?
Tenemos los Diplomados que necesitas.¡Haz clic aquí!

 

 

 

JPA Join Fetch es una de las opciones de las que dispone el estándar de JPA a la hora de reducir el número de consultas que se generan contra la base de datos. Algo que es bastante habitual y que degrada el rendimiento. Vamos a ver un ejemplo ,para ello partiremos de dos clases Java(Experto e Impartición) que están relacionadas (un Experto imparte charlas).

El código Java de las clases utilizando anotaciones JPA  será :

  1. package com.arquitectajava;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.persistence.CascadeType;
  5. import javax.persistence.Entity;
  6. import javax.persistence.Id;
  7. import javax.persistence.OneToMany;
  8. @Entity
  9. public class Experto {
  10. @Id
  11. private String nombre;
  12. public Experto() {
  13. super();
  14. }
  15. @OneToMany(mappedBy=«experto»,cascade=CascadeType.PERSIST)
  16. private List<Imparticion> imparticiones= new ArrayList<Imparticion>();
  17. public List<Imparticion> getImparticiones() {
  18. return imparticiones;
  19. }
  20. public void setImparticiones(List<Imparticion> imparticiones) {
  21. this.imparticiones = imparticiones;
  22. }
  23. public String getNombre() {
  24. return nombre;
  25. }
  26. public Experto(String nombre) {
  27. super();
  28. this.nombre = nombre;
  29. }
  30. public void setNombre(String nombre) {
  31. this.nombre = nombre;
  32. }
  33. public void addImparticion(Imparticion i) {
  34. imparticiones.add(i);
  35. }
  36. }
  1. package com.arquitectajava;
  2. import java.util.Date;
  3. import javax.persistence.Entity;
  4. import javax.persistence.Id;
  5. import javax.persistence.JoinColumn;
  6. import javax.persistence.ManyToOne;
  7. @Entity
  8. public class Imparticion {
  9. @Id
  10. private int id;
  11. private Date fecha;
  12. private String titulo;
  13. @ManyToOne
  14. @JoinColumn(name=«nombreExperto»)
  15. private Experto experto;
  16. public Imparticion(int id, Date fecha, String titulo, Experto experto) {
  17. super();
  18. this.id = id;
  19. this.fecha = fecha;
  20. this.titulo = titulo;
  21. this.experto = experto;
  22. }
  23. public Experto getExperto() {
  24. return experto;
  25. }
  26. public void setExperto(Experto experto) {
  27. this.experto = experto;
  28. }
  29. public int getId() {
  30. return id;
  31. }
  32. public void setId(int id) {
  33. this.id = id;
  34. }
  35. public Date getFecha() {
  36. return fecha;
  37. }
  38. public void setFecha(Date fecha) {
  39. this.fecha = fecha;
  40. }
  41. public String getTitulo() {
  42. return titulo;
  43. }
  44. public void setTitulo(String titulo) {
  45. this.titulo = titulo;
  46. }
  47. }

Vamos a construir el programa principal que nos selecciona los Expertos para luego recorrer sus imparticiones.

  1. package com.arquitectajava;
  2. import java.util.List;
  3. import javax.persistence.EntityManager;
  4. import javax.persistence.EntityManagerFactory;
  5. import javax.persistence.Persistence;
  6. import javax.persistence.TypedQuery;
  7. public class Principal {
  8. public static void main(String[] args) {
  9. EntityManagerFactory emf =
  10. Persistence.createEntityManagerFactory(«UnidadCharla»);
  11. EntityManager em = emf.createEntityManager();
  12. TypedQuery<Experto> consulta=em.createQuery(«select e from Experto e», Experto.class);
  13. List<Experto> lista=consulta.getResultList();
  14. for (Experto e: lista) {
  15. System.out.println(e.getNombre());
  16. List<Imparticion> imparticiones= e.getImparticiones();
  17. for (Imparticion i :imparticiones) {
  18. System.out.println(i.getTitulo());
  19. }
  20. }
  21. em.close();
  22. }
  23. }

Si ejecutamos el programa podremos ver el resultado en la consola:

Los datos se imprimen , pero estamos realizando 3 consultas para obtenerlos .En primer lugar se seleccionan todos los Expertos y por cada Experto se realiza una consulta para saber sus imparticiones. Este es el problema clásico de las n+1 Queries. Cuando existan 100 imparticiones , se lanzarán 101 consultas. Vamos a solventar este problema utilizando JPA Join Fetch.

JPA Join Fetch

Para ello nos bastará con modificar la consulta de JPA que estamos utilizando y obligarla a que incluya las imparticiones.

  1. package com.arquitectajava;
  2. import java.util.List;
  3. import javax.persistence.EntityManager;
  4. import javax.persistence.EntityManagerFactory;
  5. import javax.persistence.Persistence;
  6. import javax.persistence.TypedQuery;
  7. public class Principal {
  8. public static void main(String[] args) {
  9. EntityManagerFactory emf =
  10. Persistence.createEntityManagerFactory(«UnidadCharla»);
  11. EntityManager em = emf.createEntityManager();
  12. TypedQuery<Experto> consulta=em.createQuery(«select distinct e from Experto e join fetch e.imparticiones», Experto.class);
  13. List<Experto> lista=consulta.getResultList();
  14. for (Experto e: lista) {
  15. System.out.println(e.getNombre());
  16. List<Imparticion> imparticiones= e.getImparticiones();
  17. for (Imparticion i :imparticiones) {
  18. System.out.println(i.getTitulo());
  19. }
  20. }
  21. em.close();
  22. }
  23. }

Ahora la consulta es “select distinct e from Experto e join fetch e.imparticiones” obligando a JPA a incluir las imparticiones a través de un JOIN.

Ahora una sola consulta es suficiente ya que nos hemos apoyado en JPA Join Fetch. Recordemos que aunque los frameworks de persistencia aportan mucho , hay que saber utilizarlos. Un mal uso de estos frameworks puede generar los peores resultados.

Te esperamos en los próximos artículos en donde hablaremos mas acerca de estos temas que hoy en día son de importancia e interés en el mundo de la tecnología.

¿Te gustaría aprender Java Empresarial desde cero?
Tenemos los Diplomados que necesitas.¡Haz clic aquí!
About Author

NGuerrero

Post Anterior

0 0 votos
Article Rating
Suscribir
Notificar de
guest
0 Comments
Comentarios.
Ver todos los comentarios
0
¿Te gusta este articulo? por favor comentax