Hibernate在调用entityManager.remove()时是否删除引用的实体?

时间:2012-03-10 09:28:33

标签: hibernate jpa annotations

我遇到了以下(简化)问题:

我有一个多对一关系的实体:

@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的初学者,有时很难确切地看到注释对你有什么样的魔力,因为有时它会非常多。

2 个答案:

答案 0 :(得分:3)

级联删除将使Hibernate在引用的实体(或实体集合)上调用entityManager.remove()。因此,将从数据库中删除引用的实体。但它使实体实例保持不变。

请注意,在ManyToOne上使用cascade = REMOVE(或ALL)通常是一个非常糟糕的主意。您通常不希望在仅删除其中一个成员资格时删除用户。

答案 1 :(得分:2)

嗯,是的,在这种情况下它不起作用。由于您的关联实体可能已分离或未分离,为了确保您删除它们,您可以执行以下两项操作之一:

  • 如果您使用JPA2,请添加orphanRemove选项:

    @OneToMany(mappedBy =“whatever”,orphanRemoval = true)

  • 如果您使用JPA1,则必须手动删除它们。