Spring Data/JPA:如何保存具有多个子集合的项目? [英] Spring Data/JPA: How do I save an item with multiple child collections?

查看:48
本文介绍了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,除了字段,还有两个子"集合.数据:TaskNoteStateChangeHistory.

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);

这篇关于Spring Data/JPA:如何保存具有多个子集合的项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆