Entidades Managed, Transient y Detached en Hibernate y JPA

Alura
Paulo Silveira
Paulo Silveira
Compartir

Distinguir entre los estados de una entidad en JPA / Hibernate es difícil al principio. Se dice que un objeto es transiente cuando no tiene representación en la base de datos y tampoco el EntityManager lo conoce, como a continuación:

Cliente c = new Cliente();

Aquí, cualquier cambio en el objeto referido por C no generará ningún tipo de insert o update en la base de datos. Lo contrario es cuando el objeto existe en la base de datos y el EntityManager en cuestión tiene una referencia a él, esta entidad está managed, gestionada por el EntityManager. Considera en una referencia a un EntityManager en el siguiente ejemplo:

Cliente c = new Cliente(); // transiente
em.persist(c); // gestionado

O también:

Cliente c = em.find(Cliente.class, 1); // gestionado

Cuando una entidad está managed, cualquier cambio en su estado (como una llamada de setter) resultará en una actualización de la base de datos en el momento del commit.

El último caso es cuando la entidad representa algo que posiblemente esté en la base de datos, pero el EntityManager lo desconoce: la entidad está fuera de contexto, detached. Ejemplo:

Cliente c = new Cliente();
c.setId(1);

Una entidad también está detached cuando el EntityManager de donde obtuvimos este Cliente (por ejemplo, cuando hicimos un find o proveniente de una Query) ya no está abierta. Cualquier cambio en esta referencia obviamente no tendrá ningún efecto en la base de datos. Para que este cambio surta efecto, es decir, para que reattach a la entidad, primero debemos vincularla al contexto de persistencia. Tenga en cuenta que en el EntityManager puede que ya exista una entidad Cliente con esta misma id, imagina lo que sucedería si tuviéramos un método que se llamara reattach o update?

Entonces el método es el merge. Une la posible entidad con la misma id que está en el EntityManager con la informada como argumento, y devuelve la que está managed. El método merge no hace reattach. Luego:

Cliente c = new Cliente();
c.setId(1);
em.merge(c);
c.setNome("Cliente con nombre cambiado");

¡No funcionará! Aquí deberías haber tomado lo que devolvió el merge. Nota el pequeño cambio:

Cliente c = new Cliente();
c.setId(1);
c = em.merge(c);
c.setNome("Cliente con nombre cambiado");

Listo. Una pequeña introducción sobre el ciclo de vida de una entidad en relación con a un EntityManager: ¡transient (la especificación se llama new), managed y detached! También tenemos el estado removed, cuando una entidad está marcada para su eliminación.

Paulo Silveira

Paulo Silveira

Paulo Silveira é CEO e cofundador da Alura. Bacharel e mestre em Ciência da Computação pela USP, teve sua carreira de formação em PHP, Java e nas maratonas de programação. Criou o Guj.com.br, o podcast do Hipsters.tech e o Like a Boss.

Ver otros artículos sobre Programación

Whatsapp de Alura LATAMNewsletter de Alura LATAMContáctanos
Entidades Managed, Transient y Detached en Hibernate y JPA | Alura Cursos Online