我如何理解CascadeType关键字?

时间:2018-12-25 16:06:40

标签: hibernate jpa cascade

我认为CascadeType关键字与EntityManager的操作相关。
但是这些代码使我感到困惑。
像下面的代码。(对不起,很简单的代码)

Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();

parent.addChild(child1);
parent.addChild(child2);

em.persist(parent);

运行后,插入了parent,child1,child2。
没关系,直到这里,这是我的期望。

Parent foundParent = em.merge(parent); // parent has identifier
Child child1 = new Child();
Child child2 = new Child();

parent.addChild(child1);
parent.addChild(child2);

从这里开始。我开始思考em.perist != CascadeType.PERSIST

而且..此代码也相同。

Parent foundParent = em.find(Parent.class, 1);
Child child1 = new Child();
Child child2 = new Child();

parent.addChild(child1);
parent.addChild(child2);

child1,child2也已插入。

现在我很困惑。
如果在operation of EntityManagerCascadeType之间它们不相同,我又如何理解CascadeType.MERGE

对不起,我的英文简短,谢谢您的阅读。

2 个答案:

答案 0 :(得分:1)

总体上您是正确的,但是规范(JPA 2.2,第3.2.4段)也包含以下规则:

  

应用于实体X的刷新操作的语义如下:

     
      
  • 如果X是一个受管实体,则它将同步到数据库。
  •   
  • 对于从X的关系引用的所有实体Y,如果已使用级联元素值Cascade = PERSIST或Cascade = ALL注释了与Y的关系,则将持久操作应用于Y。
  •   

因此,如果将子级添加到托管父级中,并且父级-子级实体使用层叠= PERSIST注释,则将插入该子级。

可免费获得规格。它们定义了行为。因此,阅读它们是了解JPA工作原理的方式。

答案 1 :(得分:1)

持久和合并是为了保留某个对象的一个​​托管实例而设计的。

如果使用persist,则表示该对象尚不存在,因此使其成为唯一的托管实例也不会受到损害。

使用合并时,请考虑到对象的托管实例可能已经存在。您不想替换该唯一的托管实例,因为某些其他对象可能会引用它,并认为它是托管对象。

如果在对象的过时版本上使用合并,并将其作为参数传递给先前的合并,则JPA将不知道如何找到正确的对象,因为它尚无id。假定它是一个新对象,并且将创建新的托管实例。

  • CascadeType.PERSIST :级联类型presist表示save()或persist()操作级联到相关实体。
  • CascadeType.MERGE :级联类型合并意味着在合并拥有的实体时合并相关的实体。
  • CascadeType.REFRESH :级联类型刷新对refresh()操作执行相同的操作。
  • CascadeType.REMOVE :级联类型删除会在拥有实体为时删除与此设置关联的所有相关实体 删除。
  • CascadeType.DETACH :如果发生“手动分离”,则级联类型分离将分离所有相关实体。
  • CascadeType.ALL :级联类型all是上述所有级联操作的简写。