删除OneToMany关系中的实体
我无法理解从OneToMany关系中删除实体所需的最小努力。 我发现很多例子只是将实体添加到这些集合中(并且可以正常工作),但是删除实体要难得多。
我有以下课程:
@Entity public class Product { ... OneToMany(mappedBy="product", orphanRemoval=true, cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER) Set experts = new HashSet(); ... } @Entity public class Expert { ... @ManyToOne(optional=false) Product product; @ManyToOne(optional=false) Person person; ... }
(人与产品相似)
我充满了产品和专家。 我想从产品列表中删除专家,以便完全删除专家实体。 我希望以下代码就足够了:
Product aProduct = findAProduct(...); Expert anExpert aProduct.getExperts.get(...); // Just get the first expert that I want removed EntityManager em = entityManager(); em.getTransaction().begin(); aProduct.getExperts().remove(anExpert); em.merge(aProduct); em.getTransaction().commit();
要么:
em.getTransaction().begin(); em.remove(anExpert); em.getTransaction().commit();
这太简单了吗? JPA做了什么,我自己做了什么? 我之前通过使用查询解决了它,但我希望JPA能为我做到这一点。
尝试:
em.getTransaction().begin(); aProduct = em.merge(aProduct); aProduct.getExperts().remove(anExpert); em.getTransaction().commit();
问题在于合并操作,而不是删除。
根据我过去的经验,在Hibernate中删除亲子双向关系中的孩子可能非常棘手。
我通常做的是使用单向映射,即产品不包含专家组。 但是你可以实现一个getter来让所有专家使用Hibernate调用。 优点是:
- 更容易映射
- 更容易编码
- 可管理的行为
您可以随时返回并在稍后阶段实施缓存或急切提取。 而且大多数时候它们都是不必要的预成熟优化。
让它工作的方法是执行以下操作:
EntityManager em = entityManager(); // Retrieve the expert in the new EntityManager context Expert expertToDelete = em.find(Expert.class, anExpert.id); em.getTransaction().begin(); expertToDelete.getProduct().getExperts().remove(expertToDelete); expertToDelete.getPerson().getExperts().remove(expertToDelete); em.remove(expertToDelete); em.getTransaction().commit();
很可能不是通过find检索专家,而是可以在anExpert上使用merge(),但上面似乎有效。
- 为什么在Spring 3.1和hibernate 4中找到当前线程exception的No Session
- Hibernate单向父/子关系 – delete()对子表而不是删除执行更新
- 要用应用程序打包的最轻的数据库
- StaleObjectstateException行已更新或删除
- Hibernate没有在数据库中保存对象?
- java.lang.IllegalArgumentException“无法使用Spring 4和Hibernate 4设置DAO字段”
- 如何在dropwizard上使用guice自动连接HibernateBundle?
- hibernate中的本机生成器类
- 如何使用JPA和Hibernate加入两个不相关的实体