¿Hibernate elimina las entidades a las que se hace referencia al llamar a entityManager.remove ()?

I've got the following (simplified) problem:

I have a entity in a Many-To-One relationship:

@Entity
public class Membership {

    private User user;

    @ManyToOne(cascade = CascadeType.ALL)
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

}

... and the following corresponding class at the One-To-Many side:

@Entity
public class User extends Person {
    private Set<Membership> memberships = new HashSet<Membership>();

    @OneToMany(mappedBy = "user", cascade = { CascadeType.MERGE,
            CascadeType.REMOVE, CascadeType.REFRESH })
    public Set<Membership> getMemberships() {
        return memberships;
    }

    public void setMemberships(Set<Membership> memberships) {
        this.memberships = memberships;
    }
}

I've created a user called user1 and a membership mem1 vía new and linked them like this:

mem1.setUser(user1);
user1.getMemberships().add(mem1);

then I'm persisting them like this:

entityManager.getTransaction().begin();
entityManager.persist(user1);
entityManager.persist(mem1);
entityManager.getTransaction().commit();

Now I want to delete the membership. So I call:

entityManager.remove(mem1);

... recall that I've set cascade=CascadeType.REMOVE al User lado y cascade=CascadeType.ALL al Membership side. But the referenced membership mem1 is not removed from the user1 automatically, that is, user1.getMemberships() is still holding mem1! Is this the correct behavior? Does JPA never automatically remove references from objects when removing entities from the database?

This may seem like a dumb question, but I'm a beginner with JPA and sometimes it's hard to see exactly what kind of magic the annotations will perform for you, for sometimes it's quite a lot.

preguntado el 10 de marzo de 12 a las 09:03

2 Respuestas

Cascading the removal will make Hibernate call entityManager.remove() on the referenced entity (or collection of entities). The referenced entity will thus be removed from the database. But it leaves the entity instances untouched.

Note that having a cascade=REMOVE (or ALL) on a ManyToOne is usually a very bad idea. You generally don't want to remove a user when removing just one of its memberships.

respondido 10 mar '12, 09:03

Well, yes, it doesn't work great in this case. Due to the fact that your associated entities might be detached or not, in order to make sure you delete them you can do one of two things:

  • if you use JPA2, add the orphanRemove option:

    @OneToMany(mappedBy="whatever", orphanRemoval=true)

  • if you use JPA1 you have to remove them manually.

respondido 10 mar '12, 09:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.