Java Spring:将一条记录添加到列表中会突然创建一条重复记录
为了学习Spring,我将使用非常简单的页面来理解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
任务的列表
,并创建了另一个页面来添加新的任务
。我使用@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
}