programacion mundo hola english curso application and java hibernate orphan

mundo - java and hibernate



Hibernate eliminando huérfanos al actualizar colección (6)

Estoy descubriendo que los registros huérfanos no se eliminan cuando se eliminan de una colección en Hibernate. Debo estar haciendo algo simplemente mal, (¡esto es Hibernate-101!), Pero no puedo encontrarlo ...

Dado lo siguiente:

public class Book { @ManyToOne @NotNull Author author; } public class Author { @OneToMany(cascade={CascadeType.ALL}) List<Book> books; }

Y el siguiente código de actualización:

Author author = authorDAO.get(1); Book book = author.getBooks().get(0); author.getBooks().remove(0); authorDAO.update(author);

Fragmento de AuthorDAO:

@Override public void update(T entity) { getSession().update(entity); }

La siguiente prueba de la falla:

Author author = author.get(1); assertEquals(0,author.getBooks().size()); // Passes Book dbBook = bookDAO.get(book.getId()) assertNull(dbBook); // Fail! dbBook still exists! assertFalse(author.getBooks().contains(dbBook) // Passes!

En resumen, estoy encontrando:

  • Mientras que el libro se elimina de la colección de libros del autor, todavía existe en la base de datos
  • Si examino book.getAuthor().getBooks() , el libro no existe en esa colección

Esto se siente como si no estuviera vaciando la sesión o forzando una actualización de manera adecuada, pero no estoy seguro de dónde debería estar haciendo eso. En ese sentido, otros puntos que pueden estar impactando:

  • Estoy realizando lo anterior en una prueba JUnit decorada con @RunWith(SpringJUnit4ClassRunner.class)
  • Originalmente @Transactional este problema dentro de una rutina de actualización que está decorada con @Transactional , sin embargo, desde entonces la he recreado en una prueba JUnit antigua.

Cualquier consejo sería muy apreciado!

EDIT: Gracias por todos los comentarios ya. Además de los comentarios a continuación, he agregado @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) al padre, por lo que ahora es:

public class Author { @OneToMany(cascade={CascadeType.ALL}) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) List<Book> books; }

Todavía estoy encontrando los mismos resultados. DEBO faltar algo simple


Intente usar la siguiente anotación si desea un comportamiento de "dependencia transitiva".

@ org.hibernate.annotations.Cascade (CascadeType.DELETE_ORPHAN)


La opción de cascada en la anotación @OneToMany es una matriz, lo que desea es:

@OneToMany(cascade={CascadeType.ALL, CascadeType.DELETE_ORPHAN})


No estás haciendo nada malo. Simplemente no estás eliminando la entidad hijo. Puede hacer esto con un remove () explícito de la entidad secundaria (además de lo que está haciendo) o usar esa anotación que hace que se eliminen los registros huérfanos.

Además, vale la pena mencionar que CascadeType.DELETE tampoco eliminará huérfanos. Eso significa algo más. Ver JPA CascadeType.ALL no borra huérfanos.

Básicamente, para hacer esto automáticamente querrá esto en la colección en el padre:

org.hibernate.annotations.CascadeType.DELETE_ORPHAN


Parece que te estás perdiendo la anotación mappedBy . Tratar:

public class Book { @ManyToOne @NotNull Author author; } public class Author { @OneToMany(mappedBy="author", cascade={CascadeType.ALL}) List<Book> books; }


para gente que busca su solución: ahora en Hibernate, resp. JPA 2.0, esta es la manera correcta:

@OneToMany(orphanRemoval=true)


por favor agregue @onDelete tal vez este trabajo para usted

public class Author { @OneToMany(cascade={CascadeType.ALL}) @OnDelete(action = OnDeleteAction.CASCADE) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) List<Book> books; }