英文:
Spring Boot - java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
问题
以下是翻译好的内容:
我遇到了这个错误,但我无法解决这个问题。
虽然有很多关于这个主题的StackOverflow答案,但没有一个适合我的情况。
目标是先保存 Todo
,然后保存 TaskTodo
(连接 Task
和 Todo
的表)。
我尝试先保存并刷新 Todo
,然后保存 TaskTodo
,但是失败了。
有人能告诉我问题出在哪里吗?
错误信息:
> java.sql.SQLIntegrityConstraintViolationException: 无法添加或更新子行:外键约束失败(todo
.task_todo
,外键约束 FK8dn0kderp1dame65xsokdaavj
,引用 todo
的 id
)
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论