简体   繁体   English

OneToMany ManyToOne使用Hibernate删除子对象

[英]OneToMany ManyToOne removing child object with Hibernate

I'm using Spring Boot and Hibernate. 我正在使用Spring Boot和Hibernate。 Lets assume we have two entities: 假设我们有两个实体:

@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;
}

And we have two transacional methods; 我们有两种跨界方法;

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

What I understand (correct me if I'm wrong): 我的理解(如果我错了,请纠正我):

  1. We have orphanRemoval=true so deleteB_Y(int) will work. 我们有orphanRemoval=true所以deleteB_Y(int)将起作用。
  2. By setting mappedBy argument we say that class A is "the owning site" of relation. 通过设置mappedBy参数,我们可以说类A是关系的“拥有站点”。
  3. CascadeType is used when we persist/update/merge/remove class A (then it invokes persist/update/merge/remove on child property objectSet ). 当我们持久/更新/合并/删除类A时使用CascadeType(然后它在子属性objectSet上调用持久/更新/合并/删除)。 I think we can say that it protects me from situation where I end up with object of B and no object of A class (unless we manually add some B objs). 我想我们可以说这可以保护我免受最终以B对象而不是A类为对象的情况(除非我们手动添加一些B objs)。

From what I understand CascadeType should not interfare with orphanRemoval, because CascadeType takes care of things where we do 'some stuff' with A's objects (and then recursively do it to B's objects). 据我了解,CascadeType不应与orphanRemoval相互干扰,因为CascadeType负责处理我们对A的对象进行“某些处理”的事情(然后递归地对B的对象进行处理)。 And here is something that I don't understand at all. 这是我一点都不了解的东西。 Why deleteB_x(int) doesn't work and why if we remove CascadeType it starts working? 为什么deleteB_x(int)不起作用,为什么如果我们删除CascadeType,它就会开始起作用? I feel like that deleteB_X(int) is much cleaner solution to removing object B from the DB than deleteB_Y(int) , but sadly it won't work since it colides with CascadeType. 我觉得这样的deleteB_X(int)是非常清洁的解决方案,以从DB不是删除对象B deleteB_Y(int)但遗憾的是它不会工作,因为它用的CascadeType colides。

EDIT1. 编辑1。 Method deleteB_X(int) just doesn't remove object from DB, if we remove cascade = CascadeType.ALL evertyhing works just fine. 方法deleteB_X(int)只是不会从数据库中删除对象,如果我们删除cascade = CascadeType.ALL一切都可以。 Why? 为什么?

The issue was that my class A was fetched EAGER in class B instance and because of that (I assume) that there was a conflict when I was deleting B 's instance alone without taking care of the same B instance in private Set<B> objectSet . 问题是我的class Aclass B实例中被获取了EAGER ,因此(我假设)当我单独删除B的实例而不照顾private Set<B> objectSet中的相同B实例时,存在冲突。 private Set<B> objectSet Changing EAGER to LAZY or excluding CascadeType.PERSIST from @OneToMany(cascade=...) solved my issue. EAGER更改为LAZY或从@OneToMany(cascade=...)排除CascadeType.PERSIST解决了我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM