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 via 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 on the User side and cascade=CascadeType.ALL on the 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.
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.