Spring Data/JPA:如何保存具有多个子集合的项目?
我正在努力理解如何使用 Spring Data/JPA 与数据库交互.我目前正在使用简单的 H2 数据库进行测试.
I am struggling with understanding how to use Spring Data/JPA to interact with a database. I'm using the simple H2 database currently for testing purposes.
我有一个主要项目,Task
,除了字段,还有两个子"集合.数据:TaskNote
和 StateChangeHistory
.
I have a main item, Task
, that in addition to fields, also has two collections of "child" data: TaskNote
and StateChangeHistory
.
在我的任务服务类中,我有一个 @PostConstruct
方法来设置一些虚拟数据并将其保存到数据库中,以便我以后可以检索和显示它.看起来 Task
正在被保存,但没有一个孩子被保存.当我将数据加载到视图中(或在调试器中检查数据)时,子集合始终为空.
In my task service class, I have a @PostConstruct
method to set up some dummy data and save it to the database so that I can retrieve and display it later. It appears that the Task
is being saved, but none of the children are. When I load the data into a view (or inspect the data in the debugger), the child collections are always empty.
我需要做什么来确保任务及其子项都被保存?
What do I need to do to ensure that the Task and it's child items are all saved?
以下是部分代码:
Task.java:
@Entity
@NamedEntityGraph(name = "graph.task", attributeNodes = { @NamedAttributeNode("notes") })
public class Task extends AbstractEntity {
@OneToMany(mappedBy = "task")
private List<StateChangeHistory> stateHistory = new ArrayList<>();
@OneToMany(mappedBy = "task")
private List<TaskNote> notes = new ArrayList<>();
...
}
TaskNote.java:
TaskNote.java:
@Entity
public class TaskNote extends AbstractEntity {
@ManyToOne
private Task task;
...
}
TaskRepository.java:
TaskRepository.java:
public interface TaskRepository extends JpaRepository<Task, Long> {
@Override
@EntityGraph(attributePaths = { "notes" })
public List<Task> findAll();
}
TaskService.java:
TaskService.java:
@Service
public class TaskService {
private TaskRepository taskRepository;
public TaskService(TaskRepository taskRepository) {
this.taskRepository = taskRepository;
}
...
@PostConstruct
public void populateTestData() {
if (taskRepository.count() == 0) {
Task task = null;
TaskNote note = null;
// Task 1
task = new Task("Task-1");
task.setPriority(TaskPriority.HIGH);
task.setType(TaskType.RECURRING);
// Note 1
note = new TaskNote();
note.setNote("note-1");
task.getNotes().add(note);
// Note 2
note = new TaskNote();
note.setNote("note-2");
task.getNotes().add(note);
taskRepository.save(task);
// Task 2
taskRepository.save(new Task("Task-2"));
}
}
}
如您所见,我创建了一个任务对象并向其添加了两个注释,然后尝试保存它.我假设任务的保存有效,因为我可以让它们显示在我的视图中.但是,笔记列表总是空的.
As you can see, I create a task object and add two notes to it and then try to save it. I assume the save of the task works, as I can get them to display in my view. However, the notes list is always empty.
我需要做什么才能将子数据与父数据一起保存?
What do I need to do to save the child data along with the parent?
如其他答案所述,您必须使用 @OneToMany(cascade=CascadeType.ALL)
而不是 Task 注释
.
As stated in other answers you have to use @OneToMany(cascade=CascadeType.ALL)
over Task notes
.
要使代码工作,您必须设置双向实体关系:
To make code work you have to set a two-way entity relationship:
Task task = new Task("Task-1");
TaskNote note = new TaskNote();
note.setNote("note-1");
note.setTask(task); // missing in your code
task.getNotes().add(note);
taskRepository.save(task);