2

我有两个实体类AB,它们分别以双向一对多关系存在。

A.java:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "aId",
           fetch=FetchType.EAGER, orphanRemoval=true)
private Set<B> bCollection = new LinkedHashSet<B>();

B.java

  @JoinColumn(name = "A_ID", referencedColumnName = "ID", nullable=false)
  @ManyToOne(optional = false)   
  private A aId;

在一个简单的控制台应用程序中,我从数据库中获取了一个特定的 A行并尝试删除其详细信息B行之一(随机),但JPA/Hibernate不仅删除了该行 - 它甚至不发出任何DELETE语句数据库。删除B行的唯一方法是从A.java的集合 ( LinkedHashSet ) 中删除相应的实体。所以,虽然我有一个解决方法,但我想了解为什么下面的代码会失败,并且也会悄悄地失败!

public static void main(String[] args) {
    EntityManagerFactory entityManagerFactory =  Persistence.createEntityManagerFactory("testjpa");
    EntityManager em = entityManagerFactory.createEntityManager();
    EntityTransaction entityTransaction = em.getTransaction();
    entityTransaction.begin();
    A a = em.find(A.class, 1);
    B b = getARandomChildOfA(a);
    em.remove(em.merge(b));     // simple em.remove(b) doesn't work either
    entityTransaction.commit();
    em.close();
    entityManagerFactory.close();
}
4

1 回答 1

6

JPA 不会为您管理关系,因此当您在 b 上调用 remove 时,a 仍然具有对它的引用。由于引用设置了级联持久/合并,它会导致 b 在上下文中复活,撤消删除。

您必须维护引用以使您的模型与数据库中所需的内容保持同步。将要删除的对象的引用清空并设置回指针是一种很好的做法,除非您确定可以处理诸如此类的潜在不一致。

于 2012-10-30T21:54:46.593 回答