![](/img/trans.png)
[英]how to solve Cannot add or update a child row: a foreign key constraint fails
[英]How to solve Cannot add or update a child row: a foreign key constraint fails error in Spring JPA?
我正在研究 spring boot api,我有一個實體模型課程,另一個是主題。 在一門課程下,我想要一個包含多個主題的列表。我正在使用OneToMany
注釋來做到這一點。
這是我的代碼:
course.java
@Entity
@EntityListeners(AuditingEntityListener.class)
public class course {
@Override
public String toString() {
return "course [id=" + id + ", title=" + title + ", description=" + description + "]";
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<subject> getSubjects() {
return subjects;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
public String getProperty(String key) {
switch (key) {
case "title":
return this.title;
case "description":
return this.description;
case "date":
return this.date.toString();
case "id":
return Integer.toString(this.id);
default:
return "helo";
}
}
public course() {
super();
// TODO Auto-generated constructor stub
}
public course(int id, String title, List<subject> subjects, String description, Date date) {
super();
this.id = id;
this.title = title;
this.subjects = subjects;
this.description = description;
this.date = date;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
@OneToMany
private List<subject> subjects;
private String description;
@CreatedDate
@Temporal(TemporalType.DATE)
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
subject.java
@Entity
public class subject {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComplexity() {
return complexity;
}
public void setComplexity(String complexity) {
this.complexity = complexity;
}
public subject(String name, String complexity) {
super();
this.name = name;
this.complexity = complexity;
}
@Id
private String name;
private String complexity;
}
現在當我發送一個POST
請求時:
{
"title":"test course sossk",
"description":"Is it",
"subjects":[
{
"name":"java",
"complexity":"easy"
},
{
"name":"c++",
"complexity":"easy"
}
]
}
我收到這樣的錯誤:
SQL Error: 1452, SQLState: 23000
2021-07-18 20:01:48.818 ERROR 10408 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot add or update a child row: a foreign key constraint fails (`courses`.`course_subjects`, CONSTRAINT `FKgy72njp8nmip43dy1cwk43ue6` FOREIGN KEY (`subjects_name`) REFERENCES `subject` (`name`))
2021-07-18 20:01:48.819 INFO 10408 --- [nio-8080-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2021-07-18 20:01:48.861 ERROR 10408 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException:
我該如何解決這個問題? 如何添加外鍵?
任何幫助將不勝感激。
Update
course.java
@Entity
@EntityListeners(AuditingEntityListener.class)
public class course {
@Override
public String toString() {
return "course [id=" + id + ", title=" + title + ", description=" + description + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<subject> getSubjects() {
return subjects;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getProperty(String key) {
switch (key) {
case "title":
return this.title;
case "description":
return this.description;
case "date":
return this.date.toString();
case "id":
return Integer.toString(this.id);
default:
return "helo";
}
}
public course() {
super();
// TODO Auto-generated constructor stub
}
public course(int id, String title, List<subject> subjects, String description, Date date) {
super();
this.id = id;
this.title = title;
this.subjects = subjects;
this.description = description;
this.date = date;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
@OneToMany(targetEntity = subject.class,cascade = CascadeType.ALL)
private List<subject> subjects;
private String description;
@CreatedDate
@Temporal(TemporalType.DATE)
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
subject.java
@Entity
public class subject {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComplexity() {
return complexity;
}
public void setComplexity(String complexity) {
this.complexity = complexity;
}
public subject(String name, String complexity) {
super();
this.name = name;
this.complexity = complexity;
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
private String complexity;
}
@OneToMany(mappedBy="name")
private List<subject> subjects;
@ManyToOne
@JoinColumn(name="course_id", nullable=false) // should reference mapped column
private String name;
您的解決方案將是這樣的。 也請參考這個, OneToMany & ManyToOne mapping JPA / Hibernate
請參閱下文和評論中的解釋。 我使用 lombok @Data
來縮短 getter、setter、構造函數、tostring 的代碼。
// Course.java
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
mappedBy = "course", // we map the connection field in Subject entity
orphanRemoval = true // will delete Subjects linked
)
private List<Subject> subjects;
private String title;
private String description;
@CreatedDate
@Temporal(TemporalType.DATE)
private Date date;
}
// Subject.java
@Entity
@Data
public class Subject {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
// Here we complete the connection/relationship to the course
@ManyToOne
@JoinColumn(
name = "course_id",
nullable = false,
referencedColumnName = "id", // this `id` is the Course.id
foreignKey = @ForeignKey(name = "course_subject_fk")
)
private Course course;
private String name;
private String complexity;
}
總結一下關系:一個課程可以有多個科目,但一個科目只能分配給一個課程。
編輯我在這里所做的是使關系雙向。 意思是說,當您獲取課程時,它會使用fetch = FetchType.EAGER
自動獲取主題。 如果您不希望出現這種行為,您可以將該值更改為FetchType.LAZY
。 獲取主題時也會返回課程。 如果你也不想要這個,你可以使用 Lombok 的@ToString(exclude = "course")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.