Spring: Adding one record to a List suddenly creates a duplicate
To pick up Spring, I'm playing around with very simple pages to understand the annotations and the behaviors of Spring in general. To be precise, I created a page to show a list of Task and another page to add a new Task. I used @SessionAttibutes to save the list of Task in the session instead of calling a service to retrieve a full list of Task everytime I access the task list page.
This is my 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;
}
}
This is my TaskController
@Controller
@SessionAttributes("taskList")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/task-view")
public String showTaskList() {
return "task/view";
}
@GetMapping("/task-add")
public String showAddTaskForm(@ModelAttribute("task") Task newTask) {
return "task/add";
}
@PostMapping("/task-add")
public String addTask(ModelMap model, @ModelAttribute("task") Task newTask, @ModelAttribute("taskList") List<Task> taskList) {
System.out.println("ADDING NEW TASK: " + taskList.size());
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
System.out.println("DONE ADDING NEW TASK: " + taskList.size());
return "redirect:/task-view";
}
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
}
This is my 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>
This is my add.jsp
<%@ 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>
In term of the session-scoped attribute, it's working as I expect. The TaskService.retrieveTasks() function is only called the 1st time I access the view.jsp. Subsequently, the same list of task is pulled from the Session.
The problem is when I try to add two new Task on the add.jsp page, I saw the following lines in the console.
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
The 1st two lines were printed when I accessed the view.jsp for the 1st time, which is right. However, I have no idea what's happening between the ADDING NEW TASK and DONE ADDING NEW TASK lines. I'd be very grateful if someone could explain to me why the line below is adding a duplicate in my list of Task
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
I also tried to remove the taskList.add() portion and only made a service call to taskService.addTask(). In this case, there's no duplicate and my taskList is updated with one new record. However, I don't understand how the taskService could indirectly modify my taskList when there's no injection in the TaskService class.
Did I miss something?
java spring spring-mvc spring-boot session
add a comment |
To pick up Spring, I'm playing around with very simple pages to understand the annotations and the behaviors of Spring in general. To be precise, I created a page to show a list of Task and another page to add a new Task. I used @SessionAttibutes to save the list of Task in the session instead of calling a service to retrieve a full list of Task everytime I access the task list page.
This is my 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;
}
}
This is my TaskController
@Controller
@SessionAttributes("taskList")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/task-view")
public String showTaskList() {
return "task/view";
}
@GetMapping("/task-add")
public String showAddTaskForm(@ModelAttribute("task") Task newTask) {
return "task/add";
}
@PostMapping("/task-add")
public String addTask(ModelMap model, @ModelAttribute("task") Task newTask, @ModelAttribute("taskList") List<Task> taskList) {
System.out.println("ADDING NEW TASK: " + taskList.size());
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
System.out.println("DONE ADDING NEW TASK: " + taskList.size());
return "redirect:/task-view";
}
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
}
This is my 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>
This is my add.jsp
<%@ 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>
In term of the session-scoped attribute, it's working as I expect. The TaskService.retrieveTasks() function is only called the 1st time I access the view.jsp. Subsequently, the same list of task is pulled from the Session.
The problem is when I try to add two new Task on the add.jsp page, I saw the following lines in the console.
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
The 1st two lines were printed when I accessed the view.jsp for the 1st time, which is right. However, I have no idea what's happening between the ADDING NEW TASK and DONE ADDING NEW TASK lines. I'd be very grateful if someone could explain to me why the line below is adding a duplicate in my list of Task
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
I also tried to remove the taskList.add() portion and only made a service call to taskService.addTask(). In this case, there's no duplicate and my taskList is updated with one new record. However, I don't understand how the taskService could indirectly modify my taskList when there's no injection in the TaskService class.
Did I miss something?
java spring spring-mvc spring-boot session
1
You reference the same list twice, and thus add theTasktwice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...
– M. Deinum
Nov 20 at 10:00
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47
add a comment |
To pick up Spring, I'm playing around with very simple pages to understand the annotations and the behaviors of Spring in general. To be precise, I created a page to show a list of Task and another page to add a new Task. I used @SessionAttibutes to save the list of Task in the session instead of calling a service to retrieve a full list of Task everytime I access the task list page.
This is my 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;
}
}
This is my TaskController
@Controller
@SessionAttributes("taskList")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/task-view")
public String showTaskList() {
return "task/view";
}
@GetMapping("/task-add")
public String showAddTaskForm(@ModelAttribute("task") Task newTask) {
return "task/add";
}
@PostMapping("/task-add")
public String addTask(ModelMap model, @ModelAttribute("task") Task newTask, @ModelAttribute("taskList") List<Task> taskList) {
System.out.println("ADDING NEW TASK: " + taskList.size());
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
System.out.println("DONE ADDING NEW TASK: " + taskList.size());
return "redirect:/task-view";
}
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
}
This is my 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>
This is my add.jsp
<%@ 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>
In term of the session-scoped attribute, it's working as I expect. The TaskService.retrieveTasks() function is only called the 1st time I access the view.jsp. Subsequently, the same list of task is pulled from the Session.
The problem is when I try to add two new Task on the add.jsp page, I saw the following lines in the console.
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
The 1st two lines were printed when I accessed the view.jsp for the 1st time, which is right. However, I have no idea what's happening between the ADDING NEW TASK and DONE ADDING NEW TASK lines. I'd be very grateful if someone could explain to me why the line below is adding a duplicate in my list of Task
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
I also tried to remove the taskList.add() portion and only made a service call to taskService.addTask(). In this case, there's no duplicate and my taskList is updated with one new record. However, I don't understand how the taskService could indirectly modify my taskList when there's no injection in the TaskService class.
Did I miss something?
java spring spring-mvc spring-boot session
To pick up Spring, I'm playing around with very simple pages to understand the annotations and the behaviors of Spring in general. To be precise, I created a page to show a list of Task and another page to add a new Task. I used @SessionAttibutes to save the list of Task in the session instead of calling a service to retrieve a full list of Task everytime I access the task list page.
This is my 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;
}
}
This is my TaskController
@Controller
@SessionAttributes("taskList")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/task-view")
public String showTaskList() {
return "task/view";
}
@GetMapping("/task-add")
public String showAddTaskForm(@ModelAttribute("task") Task newTask) {
return "task/add";
}
@PostMapping("/task-add")
public String addTask(ModelMap model, @ModelAttribute("task") Task newTask, @ModelAttribute("taskList") List<Task> taskList) {
System.out.println("ADDING NEW TASK: " + taskList.size());
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
System.out.println("DONE ADDING NEW TASK: " + taskList.size());
return "redirect:/task-view";
}
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
}
This is my 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>
This is my add.jsp
<%@ 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>
In term of the session-scoped attribute, it's working as I expect. The TaskService.retrieveTasks() function is only called the 1st time I access the view.jsp. Subsequently, the same list of task is pulled from the Session.
The problem is when I try to add two new Task on the add.jsp page, I saw the following lines in the console.
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
The 1st two lines were printed when I accessed the view.jsp for the 1st time, which is right. However, I have no idea what's happening between the ADDING NEW TASK and DONE ADDING NEW TASK lines. I'd be very grateful if someone could explain to me why the line below is adding a duplicate in my list of Task
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
I also tried to remove the taskList.add() portion and only made a service call to taskService.addTask(). In this case, there's no duplicate and my taskList is updated with one new record. However, I don't understand how the taskService could indirectly modify my taskList when there's no injection in the TaskService class.
Did I miss something?
java spring spring-mvc spring-boot session
java spring spring-mvc spring-boot session
edited Nov 20 at 7:23
asked Nov 20 at 7:13
Mr.J4mes
6,68563875
6,68563875
1
You reference the same list twice, and thus add theTasktwice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...
– M. Deinum
Nov 20 at 10:00
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47
add a comment |
1
You reference the same list twice, and thus add theTasktwice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...
– M. Deinum
Nov 20 at 10:00
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47
1
1
You reference the same list twice, and thus add the
Task twice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...– M. Deinum
Nov 20 at 10:00
You reference the same list twice, and thus add the
Task twice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...– M. Deinum
Nov 20 at 10:00
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47
add a comment |
2 Answers
2
active
oldest
votes
The problem is in the method retrieveTasks:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
This method returns a reference to the taskCache object. Everybody with access to this reference can modify this mutable List. E.g. in PHP, if you returned an array, than by default, you would receive a copy of the array. Not in Java.
You should modify the method like this:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return new ArrayList<>(taskCache); // create copy of taskCache
}
This is in fact, what a real service would be doing. Data would be stored in a database, but you would not return a direct reference to that data. You would always pull current data from DB and materialize it in a brand new List.
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
add a comment |
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
I think that's what you're missing. taskList() method returns taskCache list and that's the list taskService modifies. So taksList and taskCache are the same object.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387965%2fspring-adding-one-record-to-a-list-suddenly-creates-a-duplicate%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The problem is in the method retrieveTasks:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
This method returns a reference to the taskCache object. Everybody with access to this reference can modify this mutable List. E.g. in PHP, if you returned an array, than by default, you would receive a copy of the array. Not in Java.
You should modify the method like this:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return new ArrayList<>(taskCache); // create copy of taskCache
}
This is in fact, what a real service would be doing. Data would be stored in a database, but you would not return a direct reference to that data. You would always pull current data from DB and materialize it in a brand new List.
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
add a comment |
The problem is in the method retrieveTasks:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
This method returns a reference to the taskCache object. Everybody with access to this reference can modify this mutable List. E.g. in PHP, if you returned an array, than by default, you would receive a copy of the array. Not in Java.
You should modify the method like this:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return new ArrayList<>(taskCache); // create copy of taskCache
}
This is in fact, what a real service would be doing. Data would be stored in a database, but you would not return a direct reference to that data. You would always pull current data from DB and materialize it in a brand new List.
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
add a comment |
The problem is in the method retrieveTasks:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
This method returns a reference to the taskCache object. Everybody with access to this reference can modify this mutable List. E.g. in PHP, if you returned an array, than by default, you would receive a copy of the array. Not in Java.
You should modify the method like this:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return new ArrayList<>(taskCache); // create copy of taskCache
}
This is in fact, what a real service would be doing. Data would be stored in a database, but you would not return a direct reference to that data. You would always pull current data from DB and materialize it in a brand new List.
The problem is in the method retrieveTasks:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
This method returns a reference to the taskCache object. Everybody with access to this reference can modify this mutable List. E.g. in PHP, if you returned an array, than by default, you would receive a copy of the array. Not in Java.
You should modify the method like this:
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return new ArrayList<>(taskCache); // create copy of taskCache
}
This is in fact, what a real service would be doing. Data would be stored in a database, but you would not return a direct reference to that data. You would always pull current data from DB and materialize it in a brand new List.
answered Nov 20 at 9:12
ygor
885513
885513
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
add a comment |
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
Damn. Thank you. I spent way too much time thinking about Spring that I didn't realize such a basic mistake in Java!
– Mr.J4mes
Nov 20 at 11:34
add a comment |
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
I think that's what you're missing. taskList() method returns taskCache list and that's the list taskService modifies. So taksList and taskCache are the same object.
add a comment |
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
I think that's what you're missing. taskList() method returns taskCache list and that's the list taskService modifies. So taksList and taskCache are the same object.
add a comment |
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
I think that's what you're missing. taskList() method returns taskCache list and that's the list taskService modifies. So taksList and taskCache are the same object.
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
I think that's what you're missing. taskList() method returns taskCache list and that's the list taskService modifies. So taksList and taskCache are the same object.
edited Nov 20 at 9:06
answered Nov 20 at 8:51
Ilya Sazonov
20624
20624
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387965%2fspring-adding-one-record-to-a-list-suddenly-creates-a-duplicate%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You reference the same list twice, and thus add the
Tasktwice to the same list. The dangers of caching... Instead of trying to sync the cache just add it once in the service and just refresh the cached list. Instead of trying to manually keep them up-to-date...– M. Deinum
Nov 20 at 10:00
@M.Deinum Thank you for pointing out my mistake. I tried to implement a simple example to learn Spring. I thought I was misunderstanding Spring in some way and I never realized I made such a basic Java mistake.
– Mr.J4mes
Nov 20 at 11:47