我如何理解 CascadeType 关键字?
How do I understand CascadeType keyword?
我认为 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 EntityManager
和 CascadeType
不一样,我怎么能理解 CascadeType.MERGE
呢?
抱歉我的英语很短,感谢您的阅读。
总的来说你是对的,但规范(JPA 2.2,第 3.2.4 段)也包含这些规则:
The semantics of the flush operation, applied to an entity X are as follows:
- If X is a managed entity, it is synchronized to the database.
- For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.
因此,如果将子项添加到托管父项,并且父子实体注释为 cascade = PERSIST,则插入子项。
规格是免费提供的。它们定义了行为。因此,阅读它们是您了解 JPA 工作原理的方式。
持久化和合并被设计为一种保留特定对象的一个托管实例的方法。
如果您使用 persist,则意味着该对象尚不存在,因此将其设为唯一的托管实例并没有什么坏处。
当您使用合并时,您考虑到对象的托管实例可能已经存在。您不想替换那个唯一的托管实例,因为其他一些对象可能会引用它,并认为它是托管对象。
如果您对作为参数传递给上一个合并的对象的过时版本使用合并,JPA 不知道如何找到正确的对象,因为它还没有 ID。假定它是一个新对象,将创建新的托管实例。
- CascadeType.PERSIST : 级联类型 presist 表示 save() 或 persist() 操作级联到相关实体。
- CascadeType.MERGE : 级联式合并是指在合并所属实体时合并相关实体。
- CascadeType.REFRESH: 级联类型刷新对 refresh() 操作做同样的事情。
- CascadeType.REMOVE: cascade type remove 当拥有实体为
已删除。
- CascadeType.DETACH: 如果发生“手动分离”,级联类型分离会分离所有相关实体。
- CascadeType.ALL : 对于上述所有级联操作,级联类型都是 shorthand。
我认为 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 EntityManager
和 CascadeType
不一样,我怎么能理解 CascadeType.MERGE
呢?
抱歉我的英语很短,感谢您的阅读。
总的来说你是对的,但规范(JPA 2.2,第 3.2.4 段)也包含这些规则:
The semantics of the flush operation, applied to an entity X are as follows:
- If X is a managed entity, it is synchronized to the database.
- For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.
因此,如果将子项添加到托管父项,并且父子实体注释为 cascade = PERSIST,则插入子项。
规格是免费提供的。它们定义了行为。因此,阅读它们是您了解 JPA 工作原理的方式。
持久化和合并被设计为一种保留特定对象的一个托管实例的方法。
如果您使用 persist,则意味着该对象尚不存在,因此将其设为唯一的托管实例并没有什么坏处。
当您使用合并时,您考虑到对象的托管实例可能已经存在。您不想替换那个唯一的托管实例,因为其他一些对象可能会引用它,并认为它是托管对象。
如果您对作为参数传递给上一个合并的对象的过时版本使用合并,JPA 不知道如何找到正确的对象,因为它还没有 ID。假定它是一个新对象,将创建新的托管实例。
- CascadeType.PERSIST : 级联类型 presist 表示 save() 或 persist() 操作级联到相关实体。
- CascadeType.MERGE : 级联式合并是指在合并所属实体时合并相关实体。
- CascadeType.REFRESH: 级联类型刷新对 refresh() 操作做同样的事情。
- CascadeType.REMOVE: cascade type remove 当拥有实体为 已删除。
- CascadeType.DETACH: 如果发生“手动分离”,级联类型分离会分离所有相关实体。
- CascadeType.ALL : 对于上述所有级联操作,级联类型都是 shorthand。