0

我认为CascadeType关键字与EntityManager.
但是这些代码让我感到困惑。
如下代码。(对不起,非常简单的代码)

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

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

em.persist(parent);

运行后,插入了父、子1、子2。
直到这里还好,这是我的预期。

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 EntityManagerand之间不一样CascadeType,我怎么能理解CascadeType.MERGE呢?

对不起,我的英语很短,谢谢你的阅读。

4

2 回答 2

1

总的来说,您是对的,但规范(JPA 2.2,第 3.2.4 段)也包含以下规则:

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

  • 如果 X 是托管实体,则将其同步到数据库。
  • 对于由来自 X 的关系引用的所有实体 Y,如果与 Y 的关系已使用级联元素值 cascade=PERSIST 或 cascade=ALL 进行注释,则将持久操作应用于 Y。

因此,如果将子级添加到托管父级,并且父子实体使用 cascade = PERSIST 进行注释,则将插入子级。

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

于 2018-12-25T16:13:25.097 回答
1

持久化和合并被设计为保留某个对象的一个​​托管实例的一种方式。

如果您使用persist,则意味着该对象尚不存在,因此使其成为唯一的托管实例并没有什么坏处。

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

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

  • CascadeType.PERSIST:级联类型 presist 意味着 save() 或 persist() 操作级联到相关实体。
  • CascadeType.MERGE:级联类型合并意味着在合并拥有实体时合并相关实体。
  • CascadeType.REFRESH:级联类型刷新对 refresh() 操作做同样的事情。
  • CascadeType.REMOVE:级联类型 remove 删除拥有实体时删除与此设置关联的所有相关实体。
  • CascadeType.DETACH:如果发生“手动分离”,级联类型分离会分离所有相关实体。
  • CascadeType.ALL : 级联类型 all 是上述所有级联操作的简写。
于 2018-12-25T18:54:17.303 回答