【问题标题】:remove an entity in OneToMany relationship删除 OneToMany 关系中的实体
【发布时间】:2011-12-19 23:03:57
【问题描述】:

我很难理解从 OneToMany 关系中删除实体所需的最小努力。我发现很多例子只是将实体添加到这些集合中(这很好),但删除实体更难找到。

我有以下课程:

@Entity
public class Product {
    ... 
    OneToMany(mappedBy="product", orphanRemoval=true,
              cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    Set<Expert> experts = new HashSet<Expert>();
    ...
}

@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 可以为我做到这一点。

【问题讨论】:

  • 你尝试过这两种技术吗?它有什么作用?

标签: java hibernate jpa


【解决方案1】:

试试:

em.getTransaction().begin();
aProduct = em.merge(aProduct);
aProduct.getExperts().remove(anExpert);    
em.getTransaction().commit();

问题在于合并操作,而不是删除。

【讨论】:

    【解决方案2】:

    根据我过去的经验,在 Hibernate 中删除处于父子双向关系中的孩子可能非常棘手。

    我通常做的是使用单向映射,即产品不包含专家集。但是您可以实现一个 getter 来获取所有使用 Hibernate 调用的专家。优点是:

    1. 更轻松的映射
    2. 更容易编码
    3. 可管理的行为

    您可以随时返回并在稍后阶段实施缓存或急切获取。而且大多数时候它们是不必要的过早优化。

    【讨论】:

      【解决方案3】:

      使其工作的方法是执行以下操作:

      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(),但上述方法似乎有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-09
        • 2013-05-22
        • 2016-09-03
        • 2018-02-01
        • 1970-01-01
        • 2011-08-04
        • 2016-04-21
        • 1970-01-01
        相关资源
        最近更新 更多