Para muchas personas el uso de JPA First Level Cache , genera bastantes dudas .Vamos a explicar de forma breve este concepto apoyándonos en un ejemplo. ¿Qué es JPA First Level Cache? . Es el sistema que usan los frameworks de persistencia para cachear los datos en el PersistenceContext mientras una transacción esta en curso. Parece difícil de entender pero realmente no es tan complejo. Supongamos que tenemos 3 objetos personas y los vamos a persistir en una base de datos usando JPA .
package com.arquitectajava; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.FlushModeType; import javax.persistence.Persistence; public class Principal { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("UnidadBlog"); EntityManager em = emf.createEntityManager(); EntityTransaction transaccion = em.getTransaction(); transaccion.begin(); Persona p1 = new Persona("maria", "sanchez", 20); Persona p2 = new Persona("juan", "gomez", 30); Persona p3 = new Persona("angel", "ramirez", 40); em.persist(p1); em.persist(p2); em.persist(p3); transaccion.commit(); em.close(); } }
Si ejecutamos el programa podremos ver como nuestro framework de Persistencia ejecuta 3 sentencia de insert seguidas.
La mayor parte de las personas entiende que el framework simplemente convierte los objetos a consultas SQL y las ejecuta dentro de una transacción.
Realmente esto no funciona así sino que existe un intermediario denominado PersistenceContext que es el encargado de almacenar cacheados esos objetos en memoria y saber que consultas SQL se deben lanzar contra la base de datos para persistir correctamente la información.
Java JPA First Level Cache
Para entenderlo mejor vamos a modificar el ejemplo que acabamos de construir y convertirlo en lo siguiente.
package com.arquitectajava; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.FlushModeType; import javax.persistence.Persistence; public class Principal { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("UnidadBlog"); EntityManager em = emf.createEntityManager(); EntityTransaction transaccion = em.getTransaction(); transaccion.begin(); Persona p1 = new Persona("maria", "sanchez", 20); Persona p2 = new Persona("juan", "gomez", 30); Persona p3 = new Persona("angel", "ramirez", 40); em.persist(p1); em.persist(p2); em.persist(p3); Persona p_1= em.find(Persona.class, "juan"); Persona p_3= em.find(Persona.class, "angel"); em.remove(p_1); em.remove(p_3); em.persist(p_1); em.persist(p_3); transaccion.commit(); em.close(); } }
El ejemplo es muy similar pero hemos usado el EntityManager para volver a buscar nuestros objetos en la base de datos , eliminarlos de ella y volverlos a persistir. El resultado por consola debiera incluir nuevas consultas de selección , consultas de borrado y nuevas consultas de inserción. Sin embargo al ejecutar el código:
Unicamente se ejecutan tres sentencias de inserción, JPA es capaz de darse cuenta de que los objetos aunque han pasado por varias operaciones no han sufrido modificaciones significativas. Esto se debe a que nosotros todas las operaciones de modificación las realizamos contra el PersistenceContext que mantiene cacheados los objetos.
De esta manera un framework de persistencia consigue mejorar el rendimiento en cuanto a consultas SQL se refiere en un primer nivel.
Otros artículos relacionados: El concepto de EntityManager , JPA Introducción , Introducción a JTA
Hola. Si en una transacción distinta consulta a Persona, ese objeto persona sera tomada de la cache de nivel 1 o tendrá que ir a la base de datos para actualizar la cache. Mi pregunta va en que momento se destruye la cache de nivel 1, cuando termina la transacción ?.
Cuando se cierra el entity manager
¿por qué usa _ en p_1 y p_3? ¿no va eso contra los estándares Java?
Pregunto porque otra veces he visto el guión y no se si haya un momento donde sea permitido (lo he visto mucho al inicio del nombre).
Por otro lado, ¿la cache de persistencia es válida sólo durante la transacción en curso?
Bueno era para que se viene claro , que eran variables diferentes 🙂 , esta claro que no sigue los estandars 😕 .Si la cache es a nivel de transacción