代码之家  ›  专栏  ›  技术社区  ›  JoonT

我如何理解CascadeType关键字?

  •  0
  • JoonT  · 技术社区  · 6 年前

    我想 CascadeType 关键字与的操作关联 EntityManager .
    但这些代码让我困惑。
    代码如下所示。(为非常简单的代码感到抱歉)

    Parent parent = new Parent();
    Child child1 = new Child();
    Child child2 = new Child();
    
    parent.addChild(child1);
    parent.addChild(child2);
    
    em.persist(parent);
    


    在这里之前一切都很好,这是我所期待的。

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

    现在我很困惑。
    如果他们之间不一样 operation of EntityManager 级联型 ,我怎么能理解 CascadeType.MERGE

    2 回复  |  直到 6 年前
        1
  •  1
  •   JB Nizet    6 年前

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

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

    因此,如果将一个子项添加到托管父项,并且用cascade=PERSIST注释父子实体,则插入该子项。

        2
  •  1
  •   Indrakumara    6 年前

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

    如果使用persist,则意味着该对象还不存在,因此使其成为唯一的托管实例并不有害。

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

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

    • 级联型 :cascade type presist表示save()或persist()操作级联到相关实体。
    • 级联类型合并
    • 级联类型刷新 :级联类型refresh对refresh()操作执行相同的操作。
    • 级联类型。删除 删除。
    • :如果发生手动分离,级联类型分离将分离所有相关图元。
    • 全部 :cascade type all是上述所有级联操作的缩写。