Java 使用JPA注释自动从父对象中删除子对象和从子对象中删除父对象

Java 使用JPA注释自动从父对象中删除子对象和从子对象中删除父对象,java,hibernate,jpa,orm,hibernate-mapping,Java,Hibernate,Jpa,Orm,Hibernate Mapping,假设我们有3个实体对象类: class Parent { String name; List<Child> children; } class Child { String name; Parent parent; } class Toy { String name; Child child; } 类父类{ 字符串名; 列出儿童名单; } 班童{ 字符串名; 父母; } 班级玩具{ 字符串名; 儿童; } 如何使用JPA2.x(

假设我们有3个实体对象类:

class Parent {
    String name;
    List<Child> children;
}

class Child {
    String name;
    Parent parent;
}

class Toy {
    String name;
    Child child;
}
类父类{
字符串名;
列出儿童名单;
}
班童{
字符串名;
父母;
}
班级玩具{
字符串名;
儿童;
}
如何使用JPA2.x(或hibernate)注释来:

  • 父项删除时自动删除所有子项(一对多)
  • 删除子项时自动将其从子项列表中删除(多对一)
  • 儿童移除时自动删除玩具(一对一)
  • 我正在使用Hibernate4.3.5和mysql 5.1.30


    谢谢

    您应该使用
    级联类型。删除
    。这是Hibernate和JPA的常见注释。Hibernate还有另一个类似的类型
    CacadeType
    CascadeType.DELETE

  • 父项删除时自动删除所有子项(一对多)

  • 儿童移除时自动删除玩具(一对一)


  • remove
    实体状态转换应该从父级级联到子级,而不是相反

    你需要这样的东西:

    class Parent {
    
        String name;
    
        @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        List<Child> children = new ArrayList<>();
    
        public void addChild(Child child) {
            child.setParent(this);
            children.add(child);
        }
    
        public void removeChild(Child child) {
            children.remove(child);
            child.setParent(null);
        }
    }
    
    class Child {
    
        String name;
    
        @ManyToOne
        Parent parent;
        
        @OneToOne(mappedBy = "child", cascade = CascadeType.ALL, orphanRemoval = true)
        Toy toy;
    }
    
    class Toy {
        String name;
    
        @OneToOne
        Child child;
    }
    
    类父类{
    字符串名;
    @OneToMany(mappedBy=“parent”,fetch=FetchType.LAZY,cascade=CascadeType.ALL,orphan=true)
    List children=new ArrayList();
    公共无效添加子对象(子对象){
    child.setParent(this);
    添加(child);
    }
    public void removeChild(子级){
    儿童。移除(儿童);
    setParent(null);
    }
    }
    班童{
    字符串名;
    @许多酮
    父母;
    @OneTONE(mappedBy=“child”,cascade=CascadeType.ALL,orphan=true)
    玩具;
    }
    班级玩具{
    字符串名;
    @奥内托内
    儿童;
    }
    
    删除孤立实体是删除所有孤立实体示例:商店有书籍(b1、b2、b3),b1有标题(t)。在这种情况下,如果删除了商店,一些书籍(b2、b3)将被删除。B2和t仍然存在。如果使用“
    cascade=CascadeType.Remove
    ”,则只需存储,所有书籍都将被删除(仅存在“t”)

    如果指定OrphanRemoving=true,则自动删除断开连接的实体实例。这对于清除依赖对象非常有用,如果没有所有者对象的引用,这些依赖对象不应该存在


    如果仅指定了
    cascade=CascadeType.REMOVE
    ,则不会采取自动操作,因为断开关系不是移除操作。

    为什么要将移除从子对象级联到父对象,或从玩具级联到子对象。这意味着当我移除一个玩具时,我移除了这个孩子和他的父母以及他的所有孩子。我有一个奇怪的问题。我们坚持或删除一些东西,它只是添加或删除,但下一次我重新加载页面(再次查询),它就在那里,下一次再次消失,它继续随机!当我关闭EntityManagerFactory(重新启动应用程序)时,一切都会很好!我用添加/删除子方法更新了我的响应。确保始终同步父关联和子关联,以便在添加新的子关联时,父关联和子关联都知道新链接。确保您在事务中执行这些操作,您应该会没事的。仅当应用程序关闭时,才应关闭EntityManagerFactory。在
    Child
    中的
    List toys
    上映射错误。它应该是
    OneToMany
    。按签出注释。更新你的答案。是的,你是对的。它是
    OneToOne
    &只是
    Toy
    ,而不是
    List toys
    。所以,在编辑答案之前,你错了。现在它很完美了。您不想将删除操作从子级级联到父级是有道理的,但是hibernate中是否没有注释使子级删除操作导致父级集合中的子级引用被删除?我想如果没有这样的注释是可以的,但是考虑到hibernate注释可以做的所有其他事情,这似乎并不不合理。
    class Child {
     String name;
     @ManyToOne(cascade = CascadeType.REMOVE)
     Parent parent;
    }
    
    class Toy {
      String name;
      @OneToOne(cascade = CascadeType.REMOVE)
      Child child;
    }
    
    class Parent {
    
        String name;
    
        @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        List<Child> children = new ArrayList<>();
    
        public void addChild(Child child) {
            child.setParent(this);
            children.add(child);
        }
    
        public void removeChild(Child child) {
            children.remove(child);
            child.setParent(null);
        }
    }
    
    class Child {
    
        String name;
    
        @ManyToOne
        Parent parent;
        
        @OneToOne(mappedBy = "child", cascade = CascadeType.ALL, orphanRemoval = true)
        Toy toy;
    }
    
    class Toy {
        String name;
    
        @OneToOne
        Child child;
    }
    
    s->b1,b2,b3 b2->t ------after(orphanRemoval = true)--------- b2->t
    
    s->b1,b2,b3 b2->t ------ after(cascade=CascadeType.REMOVE)--------- t