JPA / Hibernate删除“child”实体 [英] JPA / Hibernate removing "child" entities

查看:98
本文介绍了JPA / Hibernate删除“child”实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



A.java:

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

B.java

  @JoinColumn(name =A_ID,referencedColumnName =ID,nullable = false)
@ManyToOne(可选项= false)
private a aId ;

在简单的控制台应用程序中,我从数据库中获取特定的 A 行并尝试删除其中的一行详细信息(随机),但 JPA / Hibernate 不仅删除行 - 它甚至不会发布任何删除向数据库发送语句。删除 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)); //简单em.remove(b)不起作用
entityTransaction.commit();
em.close();
entityManagerFactory.close();
}


解决方案

JPA不管理关系对你来说,所以当你在b上调用remove时,仍然有一个对它的引用。由于引用在其上设置了级联保持/合并集合,因此会导致b在上下文中复活,并撤销删除。

您必须维护引用以使您的模型与您希望在数据库中保持同步。除非你确定你可以处理这种潜在的不一致,否则这是一个很好的习惯,可以清除你正在移除的对象的引用并设置指针。


I have two entity classes A and B that exist in a bidirectional one-to-many relationship respectively.

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;

In a simple console application I obtain a specific A row from the database and try to delete one of its detail B rows (at random) but JPA/Hibernate not only does remove the row - it doesn't even issue any DELETE statements towards the database. The only way to remove the B row is by removing the corresponding entity from the collection (LinkedHashSet) of A.java. So, while I have a workaround, I would like to understand why the below code fails, and fails quietly too!

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();
}

解决方案

JPA doesn't manage relations for you, so while you have called remove on b, a still has a reference to it. Since the reference has a cascade persist/merge set on it, it causes b to be resurrected in the context, undoing the remove.

You must maintain references to keep your model in sync with what you want in the database. It is good practice to null out references to objects you are removing and set back pointers unless you are sure you can deal with potential inconsistencies such as this.

这篇关于JPA / Hibernate删除“child”实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆