Java 保存到数据库会创建多个条目

Java 保存到数据库会创建多个条目,java,spring-boot,hibernate,h2,vaadin14,Java,Spring Boot,Hibernate,H2,Vaadin14,我正在编写一个管理任务和相关注释的应用程序。这是一个Spring引导应用程序,它将Vaadin用于UI,并且(当前)后端上的H2数据库通过Hibernate访问 应用程序位于显示任务的“主页面”上。单击任务可以查看详细信息,也可以单击按钮转到另一个页面以查看和编辑关联的任务注释 该项目可在github中找到,网址为。我也可以在这里发布代码片段,尽管我不确定应该包括什么。评论以询问项目 我看到了我无法解释的行为。当我在“注释列表”视图中添加一个新注释,保存它,再添加另一个并保存它时,我发现第一个注

我正在编写一个管理任务和相关注释的应用程序。这是一个Spring引导应用程序,它将Vaadin用于UI,并且(当前)后端上的H2数据库通过Hibernate访问

应用程序位于显示任务的“主页面”上。单击任务可以查看详细信息,也可以单击按钮转到另一个页面以查看和编辑关联的任务注释

该项目可在github中找到,网址为。我也可以在这里发布代码片段,尽管我不确定应该包括什么。评论以询问项目

我看到了我无法解释的行为。当我在“注释列表”视图中添加一个新注释,保存它,再添加另一个并保存它时,我发现第一个注释已被复制。副本的时间戳与保存的第二张便笺的时间戳接近。如果我要添加第三个新音符,这一次第一个和第二个音符将被复制,结果总共有3个第一个音符、2个第二个音符和我刚才添加的第三个音符

我已经在关键代码点添加了调试语句,并且正在打印这些代码点涉及的实体

我还包括了一个带有注释的日志,以说明正在发生的一些事情

有人能告诉我发生了什么,我需要做些什么来纠正这个问题吗

日志记录:

NOTE: Task-1 has two existing TaskNote items associated with it (note-1 and note-2).

>>>>> Main page.
>>>>> Select Task-1 in grid.
>>>>> Click Edit Notes button.

[INFO ] 2021-04-14 15:02:25.340 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: null
[INFO ] 2021-04-14 15:02:25.358 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:02:25.361 com.fossfloors.taskapp.ui.view.NotesListView.lambda$7(NotesListView.java:104) - NOTES: [TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2]]

>>>>> Notes List page.
>>>>> Click Add button.
>>>>> Enter note 3.
>>>>> Click Save button.
>>>>> Note 3 appears in notes list.

[INFO ] 2021-04-14 15:03:05.709 com.fossfloors.taskapp.ui.view.NotesListView.saveNote(NotesListView.java:159) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:03:05.709 com.fossfloors.taskapp.ui.view.NotesListView.saveNote(NotesListView.java:160) - NOTE: TaskNote [hashCode=1422869202, note=Note 3]
[INFO ] 2021-04-14 15:03:05.731 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=1422869202, note=Note 3]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:03:05.735 com.fossfloors.taskapp.ui.view.NotesListView.lambda$7(NotesListView.java:104) - NOTES: [TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=333570519, note=Note 3]]

>>>>> Click Add button.
>>>>> Enter note 4.
>>>>> Click Save button.
>>>>> Note 4 appears in notes list. Notice that a second note 3 appears with a similar timestamp as note 4.

[INFO ] 2021-04-14 15:03:27.617 com.fossfloors.taskapp.ui.view.NotesListView.saveNote(NotesListView.java:159) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=1422869202, note=Note 3]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:03:27.618 com.fossfloors.taskapp.ui.view.NotesListView.saveNote(NotesListView.java:160) - NOTE: TaskNote [hashCode=1422869203, note=Note 4]
[INFO ] 2021-04-14 15:03:27.628 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=1422869202, note=Note 3], TaskNote [hashCode=1422869203, note=Note 4]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:03:27.634 com.fossfloors.taskapp.ui.view.NotesListView.lambda$7(NotesListView.java:104) - NOTES: [TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=333570519, note=Note 3], TaskNote [hashCode=-1887191816, note=Note 3], TaskNote [hashCode=-1221858374, note=Note 4]]

>>>>> Click Back button.
>>>>> Main page.
>>>>> Select Task-1 in grid.
>>>>> Click Edit Notes button. There are five notes.

[INFO ] 2021-04-14 15:03:44.434 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: null
[INFO ] 2021-04-14 15:03:44.439 com.fossfloors.taskapp.ui.view.NotesListView.refresh(NotesListView.java:100) - PARENT: Task [hashcode=-523436836, title=Task-1, description=null, type=RECURRING, state=OPEN, priority=HIGH, notes=[TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=333570519, note=Note 3], TaskNote [hashCode=-1887191816, note=Note 3], TaskNote [hashCode=-1221858374, note=Note 4]], dateClosed=null, dateDue=null, dateStarted=null, dateCompleted=null]
[INFO ] 2021-04-14 15:03:44.444 com.fossfloors.taskapp.ui.view.NotesListView.lambda$7(NotesListView.java:104) - NOTES: [TaskNote [hashCode=-331664091, note=note-1], TaskNote [hashCode=-823479065, note=note-2], TaskNote [hashCode=333570519, note=Note 3], TaskNote [hashCode=-1887191816, note=Note 3], TaskNote [hashCode=-1221858374, note=Note 4]]

我浏览了一下您的git,我认为问题在于您保存了一个与
任务注释
列表具有级联关系的
任务
,但是您传递了一个过时的
任务
实例,该实例没有您以前保存的所有
任务注释

确保保存后更新
parentTask
,以便它跟踪其当前(持久化!)任务注释。这应该确保在后续保存时不会复制数据库中的关系。保存后,您已经对视图执行了
refresh()
,但仍然忘记了更新那里的parentTask实例。
以下是如何改进
刷新
方法:

private void refresh() {
    logger.info("PARENT: {}", parentTask);
    if (parentTask != null) {
      Optional<Task> optTask = taskService.findById(parentTask.getId());
      optTask.ifPresent(task -> {
        logger.info("NOTES: {}", task.getNotes());
        this.parentTask = task;    // UPDATE PARENTTASK INSTANCE HERE!!
        grid.setItems(task.getNotes());
      });
    } else {
      grid.setItems();
    }
  }
private void refresh(){
info(“父:{}”,parentTask);
if(parentTask!=null){
可选optTask=taskService.findById(parentTask.getId());
optTask.ifPresent(任务->{
info(“NOTES:{}”,task.getNotes());
this.parentTask=task;//在此处更新parentTask实例!!
setItems(task.getNotes());
});
}否则{
setItems();
}
}

似乎您正在将它们添加到
列表
或其他
集合
中,并每次保存整个集合。但是我们没有密码,所以这是最好的猜测