OneToMany ManyToOne使用Hibernate移除子对象

时间:2017-11-21 00:29:55

标签: java spring hibernate one-to-many

我正在使用Spring Boot和Hibernate。 让我们假设我们有两个实体:

@Entity
public class A{
    @OneToMany(mappedBy = "objectA",fetch = FetchType.EAGER,cascade = CascadeType.ALL,orphanRemoval=true)
    private Set<B> objectSet = new HashSet<>();
}
@Entity
public class B{
    @ManyToOne
    private A objectA;
}

我们有两种交易方式;

deleteB_X(int idB){
    entityManager.remove(entityManager.find(idB,B.class));
}
deleteB_Y(int idB){
    B obj=entityManager.find(idB,B.class);
    obj.getObjectA().getObjectSet().remove(obj);
}

我的理解(如果我错了,请纠正我):

  1. 我们orphanRemoval=true因此deleteB_Y(int)将有效。
  2. 通过设置mappedBy参数,我们说A类是“拥有者” 网站“的关系。
  3. 当我们持久化/更新/合并/删除类A(然后它在子属性objectSet上调用persist / update / merge / remove)时使用CascadeType。我想我们可以说它保护我免受B对象和A类对象的影响(除非我们手动添加一些B objs)。
  4. 根据我的理解,CascadeType不应该与orphanRemoval交互,因为CascadeType会处理我们用A的对象做“某些东西”的事情(然后以递归的方式对B的对象进行处理)。这是我根本不懂的东西。 为什么deleteB_x(int)不起作用以及为什么我们删除CascadeType它开始工作?我觉得deleteB_X(int)是比deleteB_Y(int)更清晰的从DB中删除对象B的解决方案,但遗憾的是它不会起作用,因为它与CascadeType一致。

    EDIT1。 方法deleteB_X(int)只是不从DB中删除对象,如果我们删除cascade = CascadeType.ALL evertyhing工作正常。为什么呢?

1 个答案:

答案 0 :(得分:0)

问题是我的class A已在EAGER个实例中被class B提取,因此(我假设)在删除B时出现了冲突单独使用实例而不管理B中的相同private Set<B> objectSet实例。将EAGER更改为LAZY或从CascadeType.PERSIST中排除@OneToMany(cascade=...)解决了我的问题。