2011-11-29 19 views
11

? Estoy haciendo algunas operaciones CRUD usando JPA. Para actualizar un objeto que es la forma correcta de hacerlo?¿Cuál es la mejor manera de actualizar la entidad en JPA

A través de la consulta de actualización oa través del método find de EntityManager? Tengo un objeto Employee que necesito actualizar. ¿Cuál es la forma correcta? Para facilidad, el método find es bueno, así que usé el método find().

Por favor, guíame.

Respuesta

26

Usando executeUpdate() en la API Query es más rápido, ya que no pasa por el contexto persistente .Sin embargo, pasando por alto el contexto persistente haría que el estado de la instancia en la memoria y los valores reales de ese registro en la base de datos no están sincronizados.

Consideremos el siguiente ejemplo:

Employee employee= (Employee)entityManager.find(Employee.class , 1); 
entityManager 
    .createQuery("update Employee set name = \'xxxx\' where id=1") 
    .executeUpdate(); 

Después del lavado, el nombre en la base de datos se actualiza con el nuevo valor, pero el ejemplo empleado en la memoria aún conserva el valor original .Tienes llamar entityManager.refresh(employee) para recargar el nombre actualizado del DB a la instancia del empleado. Suena extraño si los códigos todavía tienen que manipular la instancia del empleado después de la descarga, pero se olvida de actualizar() la instancia del empleado ya que la instancia del empleado todavía contiene los valores originales.

Normalmente, executeUpdate() se utiliza en el proceso de actualización masiva, ya que es más rápido debido a pasar por el contexto persistente

La forma correcta para actualizar una entidad es que se acaba de establecer las propiedades que desea actualizar a través de los emisores y deje que el JPA genere la actualización de SQL durante el vaciado en lugar de escribirlo manualmente.

Employee employee= (Employee)entityManager.find(Employee.class ,1); 
    employee.setName("Updated Name"); 
+0

@Ken Chan, 'entityManager.find (Employee.class, 1)' y 'employee.setName (" Nombre actualizado) 'causa dos consultas: seleccionar y actualizar. ¿Qué sucede si solo queremos una consulta cuando actualizando la entidad? ¿Es posible? – inherithandle

+0

Odio la forma en que se realizan las actualizaciones en JPA. Puede causar muchas actualizaciones accidentales y efectos secundarios. A veces ni siquiera sabes que estás haciendo una actualización. – ceklock

+0

¿Alguna manera de actualizar todas las propiedades con un nuevo objeto en lugar de hacerlo una por una? –

4

Eso depende de lo que quieras hacer, pero como dijiste, obtener una referencia de entidad usando find() y luego simplemente actualizar esa entidad es la manera más fácil de hacerlo.

No me molestaría sobre las diferencias de rendimiento de los distintos métodos a menos que tenga fuertes indicios de que esto realmente importa.

+0

¿Podemos usar find() para obtener el obj aObj y luego usar aObj = new MyObj (// ...) para actualizar el objeto? No vi un ejemplo como este en ninguna parte –

0

Depende del número de entidades que se van a actualizar, si tiene un gran número de entidades que utilizan JPA Query Update es mejor ya que no tiene que cargar todas las entidades de la base de datos, si va a actualizar solo una entidad que luego usa el descubrimiento y la actualización está bien.

+1

En caso de actualizaciones masivas. Pero esto también rompe el aislamiento entre el código y la base de datos, la mayoría de las ventajas de JPA –

+0

sí lo hace, pero hay instancias en las que no se pueden obtener todos los registros y luego actualizarlos, no es la solución aceptable en un contexto dado, por lo que su uso depende del contexto. Además, cuando dije Update Query, quise decir "JPA Update Query", no "SQL Update Query", por lo que todavía eres bastante independiente de la base de datos. – mprabhat

+0

La consulta de actualización de JPA se traduce en consulta SQL, y aún así rompe la abstracción de objetos. Pero hay casos de uso legítimos –

Cuestiones relacionadas