簡體   English   中英

如何解決無法添加或更新子行:Spring JPA 中的外鍵約束失敗錯誤?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM