我遇到了以下(简化)问题:
我有一个多对一关系的实体:
@Entity
public class Membership {
private User user;
@ManyToOne(cascade = CascadeType.ALL)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
......以及一对多方面的以下相应课程:
@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;
}
}
我已经通过user1
创建了一个名为mem1
的用户和一个成员资格new
,并将其链接为:
mem1.setUser(user1);
user1.getMemberships().add(mem1);
然后我就像这样坚持他们:
entityManager.getTransaction().begin();
entityManager.persist(user1);
entityManager.persist(mem1);
entityManager.getTransaction().commit();
现在我要删除会员资格。所以我打电话给:
entityManager.remove(mem1);
...请回忆一下,我已在cascade=CascadeType.REMOVE
侧设置User
,在cascade=CascadeType.ALL
侧设置Membership
。但引用的成员资格mem1
并未自动从user1
中删除,也就是说,user1.getMemberships()
仍然保留mem1
!这是正确的行为吗?从数据库中删除实体时,JPA是否永远不会自动从对象中删除引用?
这可能看起来像一个愚蠢的问题,但我是JPA的初学者,有时很难确切地看到注释对你有什么样的魔力,因为有时它会非常多。
答案 0 :(得分:3)
级联删除将使Hibernate在引用的实体(或实体集合)上调用entityManager.remove()
。因此,将从数据库中删除引用的实体。但它使实体实例保持不变。
请注意,在ManyToOne上使用cascade = REMOVE(或ALL)通常是一个非常糟糕的主意。您通常不希望在仅删除其中一个成员资格时删除用户。
答案 1 :(得分:2)
嗯,是的,在这种情况下它不起作用。由于您的关联实体可能已分离或未分离,为了确保您删除它们,您可以执行以下两项操作之一:
如果您使用JPA2,请添加orphanRemove选项:
@OneToMany(mappedBy =“whatever”,orphanRemoval = true)
如果您使用JPA1,则必须手动删除它们。