Java Spring:将一条记录添加到列表中会突然创建一条重复记录

Java Spring:将一条记录添加到列表中会突然创建一条重复记录,java,spring,spring-mvc,spring-boot,session,Java,Spring,Spring Mvc,Spring Boot,Session,为了学习Spring,我将使用非常简单的页面来理解Spring的注释和行为。准确地说,我创建了一个页面来显示任务的列表,并创建了另一个页面来添加新的任务。我使用@sessionatibutes保存会话中的任务列表,而不是每次访问任务列表页面时调用服务来检索任务的完整列表 这是我的TaskService @Service public class TaskService { private List<Task> taskCache = new ArrayList<Task&g

为了学习Spring,我将使用非常简单的页面来理解Spring的注释和行为。准确地说,我创建了一个页面来显示
任务的列表
,并创建了另一个页面来添加新的
任务
。我使用
@sessionatibutes
保存会话中的任务列表,而不是每次访问任务列表页面时调用服务来检索任务的完整列表

这是我的
TaskService

@Service
public class TaskService {
  private List<Task> taskCache = new ArrayList<Task>();

  public List<Task> retrieveTasks() {
    System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
    return taskCache;
  }

  public Task addTask(String title, String desc, Date targetDate) {
    Task newTask = new Task(title, desc, targetDate);
    taskCache.add(newTask);

    return newTask;
  }
}
这是我的
view.jsp

<html>
  <head>
    <title>Task Page</title>
  </head>
  <body>
    This is your task list:
    ${taskList}

    <div>
      <a href="task-add">Add a task</a>
    </div>
  </body>
</html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
  <head>
    <title>Task Page</title>
  </head>
  <body>
    <form:form method="POST" action="/task-add" modelAttribute="task">
      <div>
        <form:label path="title">Title</form:label>
        <form:input path="title" />
      </div>

      <div>
        <form:label path="desc">Description</form:label>
        <form:input path="desc" />
      </div>

      <div>
        <input type="submit" value="Add">
      </div>
    </form:form>
  </body>
</html>
就会话作用域属性而言,它的工作方式与我预期的一样。
TaskService.retrieveTasks()
函数仅在我第一次访问
view.jsp
时调用。随后,从会话中提取相同的任务列表

问题是,当我试图在
add.jsp
页面上添加两个新的
Task
时,我在控制台中看到了以下几行

CALLING TASK SERVICE TO GET LIST OF TASKS
GETTING TASK LIST FOR THE FIRST TIME
ADDING NEW TASK: 0
DONE ADDING NEW TASK: 2
ADDING NEW TASK: 2
DONE ADDING NEW TASK: 4
前两行是在我第一次访问
view.jsp
时打印的,没错。但是,我不知道
添加新任务
完成添加新任务
行之间发生了什么。如果有人能向我解释为什么下面这行在我的
任务列表中添加了重复项,我将不胜感激

taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
我还试图删除
taskList.add()
部分,只对
taskService.addTask()
进行了一次服务调用。在这种情况下,没有重复项,并且我的
任务列表
会更新为一条新记录。但是,我不明白当
任务服务
类中没有注入时,
任务服务
如何间接修改我的
任务列表

我错过了什么吗?

@ModelAttribute(“任务列表”)
  @ModelAttribute("taskList")
  public List<Task> taskList() {
    System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
    return taskService.retrieveTasks();
  }
公共列表任务列表(){ System.out.println(“调用任务服务以获取任务列表”); return taskService.retrieveTasks(); }

我想这就是你错过的。方法返回taskCache列表,这是taskService修改的列表。所以taksList和taskCache是同一个对象

问题出在方法
retrieveTasks

public List<Task> retrieveTasks() {
    System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
    return taskCache;
}

事实上,这就是真正的服务所要做的。数据将存储在数据库中,但不会返回对该数据的直接引用。您总是从数据库中提取当前数据,并将其具体化到一个全新的列表中。

您引用同一个列表两次,然后将
任务添加到同一个列表中两次。缓存的危险。。。不要尝试同步缓存,只需在服务中添加一次缓存,然后刷新缓存列表即可。与其手动更新,不如…。@M.Deinum感谢您指出我的错误。我试图实现一个简单的示例来学习Spring。我以为我在某种程度上误解了Spring,但我从未意识到我犯了这样一个基本的Java错误。非常感谢。我花了太多时间思考Spring,以至于我没有意识到Java中存在这样一个基本的错误!
public List<Task> retrieveTasks() {
    System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
    return taskCache;
}
public List<Task> retrieveTasks() {
        System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
        return new ArrayList<>(taskCache); // create copy of taskCache
}