-1

I am making a todo app and whenever I am trying to update an object using put, but each time it is creating a whole new object and storing it.

Here is my Controller:

        package com.todo.example.todoexample.controllers;

import com.todo.example.todoexample.models.Task;
import com.todo.example.todoexample.repositories.TaskRepository;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
public class TaskController {

    private TaskRepository taskRepository;

    public TaskController(TaskRepository taskRepository) {
        this.taskRepository = taskRepository;
    }

    @PostMapping(
            path = "/create",
            consumes = {
                    MediaType.APPLICATION_XML_VALUE,
                    MediaType.APPLICATION_JSON_VALUE
            },
            produces = {
                    MediaType.APPLICATION_XML_VALUE,
                    MediaType.APPLICATION_JSON_VALUE
            }
    )
    public void createTask(@Valid @RequestBody Task task) {
        task.setTitle(task.getTitle());
        task.setMessage(task.getMessage());

        taskRepository.save(task);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteTask(@PathVariable String id) {
        taskRepository.deleteById(id);

        return ResponseEntity.noContent().build();
    }

    @RequestMapping("/")
    public List<Task> getAllTasks() {
        return taskRepository.findAll();
    }

   /* @PutMapping(
            path = "/create/{id}",
            consumes = {
                    MediaType.APPLICATION_XML_VALUE,
                    MediaType.APPLICATION_JSON_VALUE
            },
            produces = {
                    MediaType.APPLICATION_XML_VALUE,
                    MediaType.APPLICATION_JSON_VALUE
            }
    )
    public void updateTask(@PathVariable String id, @Valid @RequestBody Task task) {
        taskRepository.findById(id);
        task.setTitle(task.getTitle());
        task.setMessage(task.getMessage());

        taskRepository.save(task);


    }*/
}

I have tried to use mongotemplate but it does not really work, I believe this is because I am trying to take in a new object and store it each time. However I am unsure what object to store the task on. As I believe I need to findById, store that variable and then set title and message and then save it! The only problem is, I do not know what object to use. Any help would be great

Oliver Darby
  • 454
  • 1
  • 6
  • 15
  • can you please add the code in post instead of images – Ryuzaki L Dec 17 '20 at 15:40
  • [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – xlecoustillier Dec 17 '20 at 15:43
  • Hi, can it be that storedTask in the line ```Task storedTask = task.get(id);``` is null? Why do you want to keep a Map with tasks in the controller when you can let the taskRepository keep track on them? – Kaj Hejer Dec 17 '20 at 15:45
  • I have changed the update task to stop using a map and use the repo however, I am unsure what variable to set it as or what to do from here in my controller – Oliver Darby Dec 17 '20 at 16:10

2 Answers2

0

Your variable named task has been declared like so:

public Map<String, Task> task;

Meaning that is effectively a null Map object. Invoking get on it is the reason why you get the NPE.

Either initialize the task Map correctly or change the implementation to fetch a Task object from your database (using the related repository) -- which seems like the correct thing to do.

akortex
  • 5,067
  • 2
  • 25
  • 57
  • I have tried to use map in orde to be able to get the task and then update the set message and set title. If i was to use the repo, id findById but then would i set that to a variable and somehow update the message and title from that? – Oliver Darby Dec 17 '20 at 16:02
  • Seems that you are lacking in basic OOP principles. The idea here is to retrieve the `Task` object from the database, set the new values on it (via the setters) and then update the object in the database via `Repository#update`. That's the whole gist of this thing. – akortex Dec 18 '20 at 09:26
  • Hi, I worked it out, it was actually because the updatetask could be null so it needed to catch that error! – Oliver Darby Dec 18 '20 at 10:01
0

The answer for this was that updateTask could be null so it needed validation in place incase this fails;

Here is the updated method and now it all works:

 public void updateTask(@PathVariable String id, @Valid @RequestBody Task task) {
    Task updatedTask = taskRepository.findById(id).orElse(null);
    assert updatedTask != null;
    updatedTask.setTitle(task.getTitle());
    updatedTask.setMessage(task.getMessage());

    taskRepository.save(updatedTask);
}
Oliver Darby
  • 454
  • 1
  • 6
  • 15