Spring Boot – java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

huangapple go评论135阅读模式
英文:

Spring Boot - java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

问题

以下是翻译好的内容:

我遇到了这个错误,但我无法解决这个问题。

虽然有很多关于这个主题的StackOverflow答案,但没有一个适合我的情况。

目标是先保存 Todo,然后保存 TaskTodo(连接 TaskTodo 的表)。

我尝试先保存并刷新 Todo,然后保存 TaskTodo,但是失败了。

有人能告诉我问题出在哪里吗?

错误信息:

> java.sql.SQLIntegrityConstraintViolationException: 无法添加或更新子行:外键约束失败(todo.task_todo,外键约束 FK8dn0kderp1dame65xsokdaavj,引用 todoid

Assignment - 父抽象类:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Assignment {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;

}

Todo - 领域类:

@Entity
public class Todo extends Assignment {

    private boolean isChecked;

    @OneToMany(mappedBy = "todo")
    Set<TaskTodo> taskTodoSet;
}

Task - 领域类:

@Entity
public class Task extends Assignment {

    private String description;

    @OneToMany(mappedBy = "task")
    public
    Set<TaskTodo> taskTodoSet;

    public Task() {}

    public Task(String name) {
        this.setName(name);
    }
}

TaskTodo - 领域类:

@Entity
public class TaskTodo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    @ManyToOne
    @JoinColumn(name = "task_id")
    Task task;

    @ManyToOne
    @JoinColumn(name = "todo_id")
    Todo todo;

    public TaskTodo(Task task, Todo todo) {
        this.task = task;
        this.todo = todo;
    }
}

保存 Todo 和 TaskTodo 的服务函数:

@Override
public void saveTodo(Todo todo, Long taskId) {
    Task task = getTaskById(taskId);
    todoRepository.saveAndFlush(todo);
    TaskTodo taskTodo = new TaskTodo(task, todo);
    taskTodoRepository.save(taskTodo);
}
英文:

I am getting this error and I cannot solve this problem.

There were plenty of StackOverflow answers based on this topic, but neither one fits me.

The goal is to save Todo and afterwards save TaskTodo(connecting table of Task and Todo).

I tried to save and flush Todo and afterwards save TaskTodo, but it failed.

Can someone tell me where is the problem?

ERROR:

> java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (todo.task_todo, CONSTRAINT FK8dn0kderp1dame65xsokdaavj FOREIGN KEY (todo_id) REFERENCES todo (id))

Assignement - Parent abstract class:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Assignment {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;

}

Todo - Domain class:

@Entity
public class Todo extends Assignment {

    private boolean isChecked;

    @OneToMany(mappedBy = "todo")
    Set<TaskTodo> taskTodoSet;
}

Task - Domain class:

@Entity
public class Task extends Assignment {

    private String description;

    @OneToMany(mappedBy = "task")
    public
    Set<TaskTodo> taskTodoSet;

    public Task() {}

    public Task(String name) {
        this.setName(name);
    }
}

TaskTodo - domain class:

@Entity
public class TaskTodo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    @ManyToOne
    @JoinColumn(name = "task_id")
    Task task;

    @ManyToOne
    @JoinColumn(name = "todo_id")
    Todo todo;

    public TaskTodo(Task task, Todo todo) {
        this.task = task;
        this.todo = todo;
    }
}

Service function for saving Todo and TaskTodo:

@Override
public void saveTodo(Todo todo, Long taskId) {
    Task task = getTaskById(taskId);
    todoRepository.saveAndFlush(todo);
    TaskTodo taskTodo = new TaskTodo(task, todo);
    taskTodoRepository.save(taskTodo);
}

答案1

得分: 0

我成功找出了问题所在。

Service函数应该是这样的:

@Override
public void saveTodo(Todo todo, Long taskId) {
    Task task = getTaskById(taskId);
    todo = todoRepository.saveAndFlush(todo); // 这一行已更改
    TaskTodo taskTodo = new TaskTodo(task, todo);
    taskTodoRepository.save(taskTodo);
}

原因是因为作为参数传递的 Todo 本身没有id,因此出现了错误。

当我添加了 todo = todoRepository.saveAndFlush(todo); 这一行后,saveAndFlush 返回的对象本身带有id。因此可以保存 TaskTodo

英文:

I managed to figure out what is the problem

Service function should look like this:

@Override
public void saveTodo(Todo todo, Long taskId) {
    Task task = getTaskById(taskId);
    todo = todoRepository.saveAndFlush(todo); // This line is changed
    TaskTodo taskTodo = new TaskTodo(task, todo);
    taskTodoRepository.save(taskTodo);
}

Reason is because Todo which was sent as parameter did not have id in itself and because of that there was an error.

When I put todo = todoRepository.saveAndFlush(todo);, saveAndFlush returned object which had id in itself. Because of that TaskTodo could be saved.

huangapple
  • 本文由 发表于 2020年9月7日 17:58:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63775314.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定