当前位置: 首页 > 知识库问答 >
问题:

Hibernate父级联删除单向子级错误

荆亦
2023-03-14

我有一个非常简单的Spring靴测试

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Bean
    public CommandLineRunner demo(ParentRepository parentRepo, ChildRepository childRepo) {
        return (args) -> {
            Parent parent = new Parent("Father");
            parent = parentRepo.save(parent);
            childRepo.save(new Child("Father", "Jack"));

            for (Child child : childRepo.findAll()) {
                System.out.println(child);
            }

            parentRepo.findById(parent.getName()).ifPresent(p -> {
                System.out.println(p);
    1.          p.getChildren().clear();//update child set parent_name=null NULL not allowed for column "PARENT_NAME";
    2.          p.setChildren(null);    //A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: springtest.Parent.children
                parentRepo.save(p);
            });

            for (Parent p : parentRepo.findAll()) {
                System.out.println(p);
            }
        };
    }

}
@Entity
public class Parent {
    @Id
    @Column(name = "NAME", nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "PARENT_NAME")
    private Set<Child> children;

    protected Parent() {}

    public Parent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Set<Child> getChildren() {
        return children;
    }

    public void setChildren(Set<Child> children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Parent[name=" + name + ", children=" + children.size() + "]";
    }

}
@Entity
public class Child {
    @Id
    @Column(name = "NAME", nullable = false)
    private String name;

    @Column(name = "PARENT_NAME", nullable = false)
    private String parentName;

    protected Child() {}

    public Child(String parentName, String name) {
        this.parentName = parentName;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Child[parentName=" + parentName + ", name=" + name + "]";
    }

}
public interface ParentRepository extends CrudRepository<Parent, String> {}
public interface ChildRepository extends CrudRepository<Child, String> {}

我要从父实体中删除子实体。链接使用的是单向,拥有实体是父实体。我试着给1打电话。getChildren().clear(),但hibernate最终生成了一个update语句,将parent_name设置为null(而不是delete where parent_name=“father”),这违反了子表中的不可为null约束。

然后我试着打电话给2。setChildren(null),这一次它给出了一个异常cascade=“all-delete-orphan”的集合不再被所属实体实例引用

你如何修复上面的,以使儿童移除工作?

共有1个答案

丁俊智
2023-03-14

作为所有者,“父项”应该是修改foraign密钥的唯一者。所以我会从“child”中删除parentName。

所以我会这样改变它:

@Entity
public class Child {
    @Id
    @Column(name = "NAME", nullable = false)
    private String name;

    protected Child() {}

    public Child(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Child[name=" + name + "]";
    }
}

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Bean
    public CommandLineRunner demo(ParentRepository parentRepo, ChildRepository childRepo) {
        return (args) -> {
            Parent parent = new Parent("Father");
            parent.add(new Child("Jack"));
            parent = parentRepo.save(parent); //the child is saved because of the cascading


            for (Child child : childRepo.findAll()) {
                System.out.println(child);
            }

            parentRepo.findById(parent.getName()).ifPresent(p -> {
                System.out.println(p);
                p.getChildren().clear();
                parentRepo.save(p); 
            });

            for (Parent p : parentRepo.findAll()) {
                System.out.println(p);
            }
        };
    }

}
 类似资料:
  • 我有一些关于“级联”的问题,在我的项目中,我有类别类,每个类可以是父类或子类。但我在同一个类中定义了哪一个是父母还是孩子。父母和孩子之间存在一对多的关系。这是我的实体类 我的问题是;当我删除子类别时,它的成功并没有问题。如果父类别有子类别,则无法删除父类别。 错误消息; Servlet.service()的servlet[调度Servlet]在上下文中与路径[]抛出异常[请求处理失败;嵌套异常or

  • 我正在从事一个java web项目,该项目使用: > Spring Hibernate/JPA MySQL-(在EasyPHP/PHPMyAdmin上)JDBC 当我想删除一些数据时,我遇到了一个错误。但是,只有当我想删除一个有子级的父行并且他的一个子行也至少有一个子行时,这个问题才存在。 目标:我希望操作/查询删除所选行及其子行和子行。 错误代码:在服务器输出中 28-Sep-2016 11:5

  • 我使用此实体表示具有自关系的类别系统,以获取子类别: 问题是当我想删除一个有子类别的类别时。我想删除所有子类别,但Java会删除此异常: 无法删除或更新父行:外键约束失败(,约束外键()引用) 我试图改变一些东西,如孤儿移除=真或级联=CascadeType。删除或尝试将级联放在单独的注释中,但不起作用。 我最后的希望是手动递归删除类别child,但这不是正确的方法。 提前感谢:)

  • 编辑:修改问题以更好地反映问题。此处最初发布的问题 我有一个父实体(< code >上下文)和一个子实体(< code >用户)。父级上的级联“删除”不会删除子级。代码如下:

  • 我有两个实体使用Spring和Hibernate

  • 问题内容: 假设我们有3个Entities对象类: 如何使用JPA2.x(或hibernate)批注来: 父级删除时(一对多)自动删除所有子级 删除后自动从子级列表中删除子级(多对一) 儿童删除时(一对一)自动删除玩具 我正在使用Hibernate 4.3.5和mysql 5.1.30。 谢谢 问题答案: 如本文所述, 实体状态转换应从父级到子级联,而不是相反。 您需要这样的东西: