2011-01-04 10 views
22

Tengo relación 1-N (el objeto tiene una lista) y quiero eliminar un elemento de la lista. ¿Cuál es la forma correcta de eliminar un elemento en la lista con JPA?jpa eliminando el elemento de la lista

¿Tengo que primero actualizar la lista y fusionar el propietario y eliminar el elemento después (si no elimino el elemento y solo fusiono el propietario, el huérfano permanecerá en DB, a la derecha)? ¿En qué secuencia se deben fusionar() y eliminar(), importa el orden de eliminar() y fusionar()?

Ejemplo de código:

List<Item> items = owner.getItems(); 
Item itemToRemove = items.get(index); 
owner.remove(itemToRemove); 
em.merge(owner); 
em.remove(itemToRemove); 

Respuesta

2

Normalmente, usted no tiene que hacer nada de eso.

Si la colección está correctamente asignada, debe llamar a items.remove (itemToRemove) y eso es todo.

Al cerrar el EntityManager (esto activa la escritura de cambios en la base de datos), debe reconocer automáticamente que el elemento ha sido eliminado (huérfano) del propietario y eliminarlo de la base de datos. Al menos Hibernate funciona de esta manera y uno puede especificar DELETE_ORPHAN como una cascada en el mapeo de la colección.

15

Esto es suficiente:

List<Item> items = owner.getItems(); 
Item itemToRemove = items.get(index); 
items.remove(itemToRemove); 

Cuando se vacía la EntityManager, se eliminará el vínculo entre owner y itemToRemove. Y si cascade está establecido en CascadeType.ALL, también se eliminará itemToRemove.

En realidad, una versión más corta (y su equivalente) es la siguiente:

List<Item> items = owner.getItems(); 
// no need to keep a reference to the object that has to be removed 
items.remove(index); 

Referencia:

+2

Contenido de esto se puede hacer owner.getItems(). Remove (index); – OJVM

+0

@OJVM volvió a leer mi publicación, comenzando por "En realidad, una versión más corta (y equivalente) es esta:" –

+0

@SeanPatrickFloyd ¿Qué pasa si la lista contiene 1 millón de entradas? ¿no será eso lento? – Ced

18

Esto debería funcionar en caso de que tenga orphanRemoval=true (JPA 2.0).

Para JPA 1 no existe una forma estándar de manejar esto. Hibernate tiene @Cascade donde puede especificar DELETE_ORPHAN

14

Gracias a todos por las respuestas. Sus respuestas son muy similares, pero hay algunas diferencias leves.

Sólo quiere asegurarse de que comprendo bien:

  1. En JPA 1.0 (en general) Tengo que llamar a remove() en entidades referenciadas. No se eliminarán con el color del administrador de entidades. De lo contrario, huérfano permanecería en DB.
  2. En JPA 1.0 con implementación de Hibernate cuando se establece DELETE_ORPHAN, la entidad a la que se hace referencia se elimina con flush del administrador de entidades. No es necesario llamar a remove().
  3. En JPA 2.0 (en general) cuando orphanRemoval = true, la entidad a la que se hace referencia se elimina con flush del administrador de entidades. No es necesario llamar a remove(). Si orphanRemoval no está configurado, se debe llamar a remove() para eliminar la entidad a la que se hace referencia.
+0

Sí, su conclusión es correcta, solo pruebo bajo JPA2.0. está bien – Scarlett

Cuestiones relacionadas