JPA (III) EntityManager métodos

En el post anterior hemos hablado sobre los distintos estados que una entidad puede tener dentro de JPA .En este artículo mostraremos el código de cada una de las operaciones básicas. Para ello  nos apoyaremos en la clase Persona. En el siguiente bloque de código hemos usado las anotaciones de @Entity para identificar el bean como una entidad a guardar en la base de datos y @Id para identificar el campo de clave primaria. Por último hemos sobrecargado los métodos hashCode y equals a la hora de comparar objetos

package es.curso.bo;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Persona {

@Id
private String nombre;
private int edad;
public Persona() {
super();

}

public Persona(String nombre, int edad) {
super();
setEdad(edad);
setNombre(nombre);
}
public String getNombre() {

return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;

}

public int getEdad() {

return edad;
}
public void setEdad(int edad) {
this.edad = edad;

}

@Override
public int hashCode() {
//simplificacion
return nombre.hashCode();
}

@Override
public boolean equals(Object obj) {
//simplificacion
Persona nueva= (Persona)obj;
return nueva.getNombre().equals(this.getNombre());

}
}

Persist()

Ya vimos anteriormente el método persist pero vamos a volverlo a mostrar ya que es el encargado de almacenar nuevas entidades en base de datos.

public static void main(String[] args) {

Persona yo = new Persona("pedro",25);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("UnidadPersonas");
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
em.persist(yo);
em.getTransaction().commit();
} catch (Exception e) {

e.printStackTrace();
}finally {
em.close();

}

}

Contains()

Como código complementario podemos apoyarnos en el método contains que comprueba si una entidad esta gestionada por el EntityManager devolviendo true o false según correspanda.


public static void main(String[] args) {

Persona yo = new Persona("pedro",25);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("UnidadPersonas");
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();

System.out.println(em.contains(yo));

em.persist(yo);

System.out.println(em.contains(yo));

em.getTransaction().commit();
} catch (Exception e) {

e.printStackTrace();
}finally {
em.close();

}

}

Find()

Este método se encarga de localizar una Entidad a traves de su clave primaria. Para ello necesita que le pasemos la clave y el tipo de Entidad a buscar. Eso si recordemos que para que nos encuentre la entidad debemos haber sobrecargado los métodos equals y hashcode de forma correcta . En nuestro ejemplo hemos utilizado una implementación básica.

public static void main(String[] args) {

EntityManagerFactory emf = Persistence
.createEntityManagerFactory("UnidadPersonas");
EntityManager em = emf.createEntityManager();
Persona yo = em.find(Persona.class, "cecilio");
System.out.println(yo.getNombre());
System.out.println(yo.getEdad());

}

Remove()

Este método se encarga de eliminar una entidad de la base de datos.


public static void main(String[] args) {

EntityManagerFactory emf = Persistence
.createEntityManagerFactory("UnidadPersonas");
EntityManager em = emf.createEntityManager();
try {

Persona yo = em.find(Persona.class, "cecilio");
em.getTransaction().begin();
em.remove(yo);
em.getTransaction().commit();
} catch (Exception e) {
em.close();
}

}

Flush()

Este método es un poco mas curioso y es el encargado de sincronizar el PersistenceContext contra la base de datos .Normalmente todo el mundo piensa que cuando nosotros invocamos el método persist() o remove() se ejecutan automaticamente las consultas contra la base de datos .Esto no es así ya que el EntityManager irá almacenando las modificaciones que nosotros realizamos sobre las entidades .Para mas adelante persistirlas contra la base de datos todas de golpe ya sea invocando flush o realizando un commit a una transacción.

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

About Cecilio Álvarez Caules

Cecilio Álvarez Caules Sun Certified Enterprise Architech (J2EE/JEE).

52 Responses to JPA (III) EntityManager métodos

  1. romaldo 10 Julio, 2017 at 16:55 #

    como guardaria un method. consulto por id y que me retorne un Email

    • Cecilio Álvarez Caules 12 Julio, 2017 at 8:49 #

      no te entiendo bien , pero en principio si buscas por id , devuelve el objeto completo con todos sus campos

  2. Camilo Restrepo 8 Mayo, 2017 at 1:36 #

    hola Cecilio primero que todo felicitarlo por tu pagina, quisiera saber como puedo eliminar un registro de una tabla que es autonumerico pero al mismo tiempo actualizar el registro. he agregado el metodo Find que se encarga de ubicar una entidad por medio de su Id pero no logro eliminar ese registro estoy manejando entityManager JPQL, espero me ayude.

    • Cecilio Álvarez Caules 9 Mayo, 2017 at 18:44 #

      Debería ser suficiente con un remove , pero para ello el bean debe estar manejado es decir le has tenido que seleccionar antes

      • Camilo Restrepo 19 Mayo, 2017 at 5:16 #

        Gracias Cecilio lo resolví creando un Query para eliminar el id asi: em.createQuery(“delete from Imagen where iddatos.iddatos=” + db.getIddatos()).executeUpdate();

        • Cecilio Álvarez Caules 19 Mayo, 2017 at 8:07 #

          me alegro 🙂

  3. Eduardo 15 Diciembre, 2016 at 16:32 #

    Hola gracias por tu post, tengo una pregunta.. actualmente estoy manejando una situacion asi:

    Localidades -> Productos -> Precios

    solo tengo un tema, con los precios ya que cada localidad maneja un precio diferente, ¿cómo pudiera relacionar eso, o que tendria que hacer para cuando precise una localidad, recuperar los productos que tiene y el precio correspondiente ?..

    actualmente tengo un manytoone (Localidad ->producto) onetomany(Producto ->precios).., o sea todas las localidades ofrecen los mismos productos, pero su precio varia por localidad, cómo pudiera canalizar eso a traves de JPA, o me recomiendas que aplique JPQL ??.. gracias desde YA.

    • Cecilio Álvarez Caules 17 Diciembre, 2016 at 7:52 #

      No se si te entiendo bien , pero lo que dices es que el precio varía por localidad para cada producto , no se pero a mi me da la sensación que te puede faltar una tabla tipo “AsignaciónPrecio” con fecha inicio y fecha fin?? y que el precio del producto varía con el tiempo y la localidad?. Es decir no puedes tener simplemente el último precio guardado ya que al imprimir una factura te saldrán con el precio nuevo. No se si te aporto algo? 🙂

  4. Javi Nozal 16 Junio, 2016 at 8:25 #

    Hola.

    Gracias por la contestación.
    Al final, edité la clase AbstractController, y en el método persist, introduje una comprobación adicional, comprobando el persistAction == PersistAction.CREATE.

    Hasta este momento, solamente se comprobaba el DELETE. Los otros dos casos (CREATE y UPDATE) eran tratados del mismo modo, y por ello la creación de un nuevo registro se trataba como un UPDATE, aún cuando existiese ya una tupla en BBDD con esa primary key,

    Ahora ya funciona correctamente.

    Muchas gracias.
    Un saludo

    • Cecilio Álvarez Caules 16 Junio, 2016 at 10:09 #

      gracias por el aporte 🙂

  5. Javi Nozal 15 Junio, 2016 at 12:11 #

    Hola.

    Tengo un entidad llamada Cliente con un identificador llamado id, que es el DNI del cliente.

    Se crean correctamente los Clientes nuevos, se modifican correctamente y se eliminan satisfactoriamente los ya existentes.

    El problema es cuando intento crear un nuevo cliente con un DNI ya existe en BBDD. Lo que hace es actualizar el cliente existente en la BBDD, en vez de lanzar un error de Cliente ya existente.

    ¿Cómo puede estar ocurriendo esto, si el campo id lo tengo marcado como @Id y en la BBDD como primary key?

    ¿He de manejar esta situación en el método find?

    Muchas gracias.

    • Cecilio Álvarez Caules 15 Junio, 2016 at 13:08 #

      Debieras usar find para buscarle eso será lo más c´modo , aunque en principio si intentases usar persist para persistir algo que ya exista saltará una excepcion

  6. Vladimir Alfaro 8 Mayo, 2016 at 18:59 #

    para todo los que vamos entramos al mundo de Hibernate/JPA este es una excelente página!!
    El tutorial es simple, rápido y muy útil!!!

    • Cecilio Álvarez Caules 9 Mayo, 2016 at 16:43 #

      gracias 🙂

  7. jonathan restrepo 30 Abril, 2016 at 1:51 #

    como se llama tu libro, es que quiero ver si lo consigo en colombia

    • Cecilio Álvarez Caules 5 Mayo, 2016 at 16:55 #

      JPA Domain Driven Design

  8. Andrés felipe 22 Noviembre, 2015 at 18:11 #

    Hola Cecilio, tengo una entidad llamada Atencion, que contiene una relación con otra llamada recaudo, y esa a su vez contiene una lista de otro tipo de entidad…

    cuando voy a guardarla por primera vez esta guarda en cascada a la perfección, pero cuando quiero hacerlo una segunda vez, esta no funciona, solo actualiza la entidad principal

    alguna idea de que pueda ser??

    saludos!

    • Cecilio Álvarez Caules 22 Noviembre, 2015 at 20:13 #

      revisa las anotaciones de cascade.persist y cascade update

  9. Marcelo 25 Septiembre, 2015 at 20:23 #

    Hola Cecilio, tengo un tema en donde tengo dos schemas de base de datos mysql, uno para seguridad y otro para la parte de negocio. ¿necesito dos entityManager? ¿como se manejan estos casos?

  10. Andrés 5 Agosto, 2015 at 19:10 #

    Hola, tengo una duda, y es que estoy realizando una consulta que me retorna todo de esta manera:

    CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    return em.createQuery(cq).getResultList();

    Lo consulto la primera vez y sale todo OK, a la segunda voy a la base de datos, cambio algunos valores, y la vuelvo a ejecutar y me retorna los mismos valores de la primera ejecución….

    a que se debe esto?

    • Cecilio Álvarez Caules 5 Agosto, 2015 at 20:03 #

      Estas manteniendo el mismo entity manager.. probablement este cacheando. Ejecuta em.refresh() a ver si tienes más suerte 🙂

  11. Paco 30 Marzo, 2015 at 19:24 #

    Buenas, mi pregunta es como pudo modificar un objeto que tiene un id string, cambiando tambien el valor del id, he conseguido modificar un objeto pero dejandole el mismo id, si lo modifico me crea uno nuevo.

    public void update (Article art, Article newArt) {//art es el articulo que quiero modificar y newArt los nuevos valores que tomara el articulo

    EntityManagerFactory emf = Persistence.createEntityManagerFactory(“mvc_SourceExplicacionPU”);
    EntityManager em = emf.createEntityManager();

    EntityTransaction tx = em.getTransaction();
    tx.begin();
    //em.merge(art);
    em.merge(newArt);
    tx.commit();

    em.close();

    emf.close();
    }

    • Cecilio Álvarez Caules 30 Marzo, 2015 at 22:14 #

      prueba a buscarle primero con find y luego modificarle con los nuevos valores

  12. Diego Hidalgo 26 Marzo, 2015 at 21:38 #

    Hola como estas, mira tengo una consulta, que pasa si tengo mi EntityManager y lo paso como parametro a otros metodos? es decir lo paso como referencia a metodos de mas bajo nivel.., hay algun problema con ello??

    • Cecilio Álvarez Caules 28 Marzo, 2015 at 11:29 #

      De entrada estarías compartiendo entre clases un objeto que gestiona un conjunto de entidades con su ciclo de vida. Estarías ampliando la vida del entity manager y normalmente esta no es su función ya que está orientado a gestionar el ciclo de vida de un pequeño grupo de entidades

  13. Alejandro 15 Marzo, 2015 at 16:52 #

    Buenas cecilio, muy buen aporte, me dirias como hacer un find mas específico, es decir, uno que no busque solamente por Pk sino que si se cuample tal condicion me devuelva la/las insrtancias.

    • Cecilio Álvarez Caules 16 Marzo, 2015 at 8:55 #

      Para ello tienes que usar el entity manager y crearte una consulta con createQuery

  14. Edgardo 4 Febrero, 2015 at 2:56 #

    property name=”eclipselink.cache.shared.default” value=”false”

  15. Edgardo 4 Febrero, 2015 at 2:19 #

    Hola Cecilo, a la hora de actualizar (merge) una entidad no tengo problema, la modificacion se refleja en la base de datos al instante y tambien al hacer una consulta en el jtable. El problema esta en que cuando consulto esa modificacion desde otra sesion no actualiza. Tengo que volver a salir y entrar, y solo asi se actualizan los datos en mi aplicacion.
    Estoy utilizando java swing y eclipselink.
    Te agradeceria que puedas darme una mano. Espero poder comprar muy pronto tu libro. Saludos desde Paraguay.

    • Edgardo 4 Febrero, 2015 at 2:54 #

      Leyendo un poco pude darme cuenta que el problema estaba en que eclipselink tiene una propiedad de almacenamiento de cache. Esto sirve para que a la hora de consultar datos tu aplicacion no necesite acudir a la base de datos.
      Esta es la propiedad que se deberia agregar al archivo de configuracion persintece.xml

      • Edgardo 4 Febrero, 2015 at 2:55 #

        “”

    • Cecilio Álvarez Caules 6 Febrero, 2015 at 13:44 #

      invoca al método refresh() de tu entitymanager

  16. Fredy Diaz 3 Diciembre, 2014 at 5:51 #

    Hola, me podria explicar como se relaciona lo expuesto aca con por ejemplo HibernateUtil.java, es esta clase una implementación particular de JPAHelper.java? Adicionalmente que pasa con el persistenc.xml vs hibernate-config.xml?

    Gracias.

    • Cecilio Álvarez Caules 3 Diciembre, 2014 at 22:36 #

      Normalmente el hibernate util lo unico que hace es almacenar SessionFactory que sería lo mismo que almacenar EntityManagerFactory como singelton

  17. Victor Doors 21 Agosto, 2014 at 9:55 #

    ¿Por qué es necesario sobrecargar los métodos hashCode y equals? En mi proyecto cojo las entidades desde las tablas de mi ORM cargando la base de datos. Estoy probando el método find de este tutorial y me pregunto porqué no funcionaría sin añadir esos métodos.

    • Cecilio Álvarez Caules 21 Agosto, 2014 at 10:04 #

      Hay en situaciones que hay que comparar por igualdad 2 objetos y en java dos objetos son iguales en principio si en memoria referencian a la misma instancia. Normalmente en un negocio se pide que dos objetos sean iguales si tienen el mismo idfactura o algo similar. De ahi la sobrecarga

  18. diego sandoval 21 Julio, 2014 at 5:37 #

    Disculpa, una pregunta tonta, descargue el último código sobre JPA para poder verlo corriendo pero no puedo verlo funcionando, ¿como lo hago para poder probar la aplicación?

  19. Carlos Delgadillo 26 Marzo, 2014 at 18:04 #

    Hola, saludos. Yo tengo una consulta.

    Cómo se actualizan las entidades cuando se hace una transacción?. Por ejemplo, tengo 3 entidades. La entidad carga, almacena en cascada una lista de facturas. La entidad cliente, posee una lista de facturas. Así mismo cada factura está ligada a un único cliente.

    Si yo elimino una carga, elimino las facturas que fueron almacenadas durante la carga, pero siguen estando presentes en la lista de facturas del cliente. Así mismo, cuando guardo nuevas facturas o realizo un cambio, estas no aparecen en la lista de facturas del cliente.

    ¿Cual es la manera correcta de manejar estos datos? No importa cuantas veces consulte, los datos no se actualizan en las otras entidades.

    Así mismo he intentado probar los métodos flush(), detach(), clear(), pero no logro entender cómo funcionan realmente, pues siempre me lanza “persistence error” cuando intento usarlos. ¿Podrías dar una explicación mas detallada del uso correcto de estos métodos y cómo puedo resolver mi problema?

    Gracias, saludos

    • Cecilio Álvarez Caules 26 Marzo, 2014 at 19:13 #

      Has probado con el atributo Cascade Delete para borrar elementos padre /hijo . Es lo que se usa habitualmente. 🙂 Te permite si eliminas el padre que los hijos se eliminen automaticamente.

  20. Nelson 4 Noviembre, 2013 at 21:16 #

    Saludos. Estoy teniendo una situación muy interesante con un proyecto de JSF y JPA. Estoy usando jpql. El negocio son las evaluaciones al personal. Cuando guardo un objeto evaluación, se guarda bien, cuando consulto evaluaciones todo bien, pero… cuando Guardo un objeto de evaluación y empiezo a consultar evaluaciones de una lista, en algunos registros, me aparece no la evaluación que estoy consultando, si no la que acabo de guardar. SIguiendo el error, llegué hasta la consulta donde me dí cuenta que los parámetros de la consulta los paso correctamente, pero la consulta jpql me envía un resultado que no es el correcto, si no el de la última evaluación guardada. qué podrá ser? Será un problema con el framework?

    • Cecilio Álvarez Caules 5 Noviembre, 2013 at 9:27 #

      No creo que sea problema del framework yo creo que es algo que se te ha escapado .Recuerda que JPA se centra mucho en los objetos . Has escrito correctamente los métodos hashcode e equals? ya que sino están sobrecargados pueden devolverte resultados que no eran los que buscabas.

      • Nelson 5 Noviembre, 2013 at 21:07 #

        Ahora, usando la aplicación el problema no ha aparecido mas. :/ Ya no se está dando, pero no me da buena impresión, porque como sabemos no hay magia. Revisaré bien las entidades. Muchas gracias.

        • Cecilio Álvarez Caules 6 Noviembre, 2013 at 13:00 #

          Bueno puede ser que algo te estuviera cacheando o similar .Esas cosas pasan 🙂

          • Pedro 28 Noviembre, 2013 at 19:39 #

            Don Cecilio muchas gracias. Lo resolví eliminando la caché de las entidades “entidadEspecífica” del EntityManagerFactory con el método EMF.getCache.evict(class);

          • Cecilio Álvarez Caules 30 Noviembre, 2013 at 11:35 #

            Me he perdido un poco con todos los comentarios 🙂 al final lo resolviste ?

            Un saludo

          • Pedro 28 Noviembre, 2013 at 19:46 #

            Incluso estuve teniendo un situación en la cual Yo tenía una lista de objetos. Alguien desde otra vista o directamente desde la base de datos elimnada un registro (un objeto de esa lista). Cuando yo hacía un find de esa entidad con JPA el objeto siempre era retornado en la lista, aparentemente porque permanece en el contexto de persistencia. Entonces… tuve que ir a vaciar la caché siempre que lo consultaba para obligar a JPA a buscarlo en la BD

  21. gustavo 6 Octubre, 2013 at 3:33 #

    hola todos los tutoriales son muy bien explicados, eh estado leyendo el libro y la verdad esta muy bien, soy de mexico DF y me gustaria comprarlo pero en las principales librerias de mexico no lo encuentro :'( espero llegue pronto, gracias por todos los aportes eh aprendido muchas cosas que se me dificultaban saludos

    • Cecilio Álvarez Caules 6 Octubre, 2013 at 16:21 #

      Al final me parece que solo esta disponible via Amazon . Ya lo siento pero cuando lo publique no pensé que tendría tanto éxito. Espero a futuro ir aprendiendo de estas cosas.

  22. Diego 4 Octubre, 2013 at 13:57 #

    Hola!, primeramente felicitarte por los tutoriales, queria pedirte si se puede subir la forma de mapeos para las relaciones Unidireccional y Bidireccional en JPA.

    Gracias!!

    • Cecilio Álvarez Caules 6 Octubre, 2013 at 16:21 #

      Si tengo tiempo intentaré publicar algo sobre esos temas . Gracias por la idea 🙂

Trackbacks/Pingbacks

  1. EntityManager, EntityManagerFactory y Singletons - Arquitectura Java - 11 Junio, 2014

    […] Arquitectura Java :EntityManager Métodos  […]

Deja un comentario