gpt4 book ai didi

java - Hibernate Parent级联删除单向子错误

转载 作者:行者123 更新时间:2023-11-30 05:38:51 26 4
gpt4 key购买 nike

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

@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 最终生成了一条更新语句,将parent_name 设置为 null(而不是删除parent_name="Father"),这违反了子表中的不可空约束。

然后我尝试调用2.setChildren(null),这次抛出异常拥有cascade="all-delete-orphan"的集合不再被拥有者引用实体实例

如何解决上述问题以使子项删除工作正常进行?

最佳答案

作为拥有实体,“父级”应该是唯一修改外键的实体。所以我会从“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);
}
};
}

}

关于java - Hibernate Parent级联删除单向子错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56102257/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com