2008-11-20 34 views
116

estoy problemas para suprimir los nodos huérfanos utilizando JPA con la siguiente asignaciónAPP CascadeType.ALL no elimina huérfanos

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner") 
private List<Bikes> bikes; 

estoy teniendo el problema de los papeles huérfanos que cuelgan alrededor de la base de datos.

Puedo utilizar la anotación org.hibernate.annotations.Cascade Etiqueta específica de Hibernate, pero obviamente no quiero vincular mi solución a una implementación de Hibernate.

EDIT: Parece que JPA 2.0 incluirá compatibilidad con esto.

Respuesta

138

Si lo está utilizando con Hibernate, tendrá que definir explícitamente la anotación CascadeType.DELETE_ORPHAN, que se puede usar junto con JPA CascadeType.ALL.

Si no tiene previsto utilizar Hibernate, primero deberá eliminar explícitamente los elementos secundarios y luego eliminar el registro principal para evitar registros huérfanos.

secuencia de ejecución

  1. recupera una fila principal que debe ser suprimido
  2. fetch elementos secundarios
  3. eliminar todos los elementos secundarios
  4. eliminar la fila principal
  5. sesión cerrada

Con JPA 2.0, ahora puede usar la opción orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true) 
+3

gracias Terminé yendo esta ruta, creo esto es un poco más de un sitio para las especificaciones de JPA. –

+12

El estándar JPA 2.0 ahora tiene deleteOrphan como atributo de @OneToMany Si está utilizando el hibernate más reciente, puede hacer @OneToMany (..., deleteOrphan = true) – jomohke

+0

¿Qué es la secuencia de ejecución cuando solo actualizo child-elements? se eliminarán los registros de huérfanos? – jAckOdE

104

Si está utilizando JPA 2.0, ahora se puede utilizar el atributo orphanRemoval=true del @xxxToMany anotación para eliminar los huérfanos.

En realidad, CascadeType.DELETE_ORPHAN ha quedado obsoleto en 3.5.2-Final.

+3

¡+1 por proporcionar la respuesta actualizada a esta pregunta! –

+5

En realidad, creo que orphanRemoval = true significa algo más, es decir, eliminar un objeto cuando lo elimine de su colección principal. Ver http://download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy – Archie

+3

no funciona con @ManyToMany como lo sé. – ses

4

acabo de encontrar esta solución, pero en mi caso no funciona:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true no tiene ningún efecto.

+1

¿Estás usando JPA2? –

+1

Necesitaba limpiar y construir antes de que el cambio entrara en vigor. – maralbjo

+0

Guau, he estado buscando una hora de por qué agregar CascadeType.ALL en mi ManyToOne no fue en cascada elimina. Limpio y construido y funciona. Gracias @maralbjo. –

2

Solo @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

Eliminar targetEntity = MyClass.class, funciona genial.

1

Para los registros, en OpenJPA antes de JPA2 era @ElementDependant.

7

se puede utilizar para eliminar @PrivateOwned huérfanos por ejemplo

@OneToMany(mappedBy = "masterData", cascade = { 
     CascadeType.ALL }) 
@PrivateOwned 
private List<Data> dataList; 
+4

Gracias @reshma, debe tenerse en cuenta que @PrivateOwned es una extensión de eclipse JPA. –

40
╔═════════════╦═════════════════════╦═════════════════════╗ 
║ Action ║ orphanRemoval=true ║ CascadeType.ALL ║ 
╠═════════════╬═════════════════════╬═════════════════════╣ 
║ delete ║  deletes parent ║ deletes parent ║ 
║ parent ║  and orphans  ║ and orphans  ║ 
╠═════════════╬═════════════════════╬═════════════════════╣ 
║ change ║      ║      ║ 
║ children ║ deletes orphans ║  nothing  ║ 
║ list  ║      ║      ║ 
╚═════════════╩═════════════════════╩═════════════════════╝ 
+1

Terrible respuesta ... Sin explicación alguna, simplemente trague una mesa ... -.- –

+0

¿Qué sucede si tengo 'cascade = CascadeType.ALL, orphanRemoval = false' y elimino el padre? ¿Eliminará niños, a pesar de que específicamente le dije que NO lo haga? – izogfif

2

que tenía el mismo problema y me preguntaba por qué esta condición abajo no borrar los huérfanos. La lista de los platos no se han eliminado en Hibernate (5.0.3.Final) cuando ejecuta una consulta de borrado nombre:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true) 
private List<Dish> dishes = new ArrayList<>(); 

Entonces me acordé de que no debe utilizar una consulta de eliminación llamado, pero el EntityManager. Como utilicé el método EntityManager.find(...) para recuperar la entidad y luego EntityManager.remove(...) para eliminarla, también se eliminaron los platos.

0

estaba usando uno correspondencia unívoca, pero el niño no estaba recibiendo eliminado de la APP estaba dando violación de clave externa

Después de usar orphanRemoval = true, cuestión se resolvió

+0

@OneToOne (cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn (name = "CHILD_OID") privado Child child; –

Cuestiones relacionadas