Learn

The .save method from the CrudRepository interface can be used both for creating new entries in the database as well as updating existing entries.

A common flow is to fetch an entry from the database by its ID, update some attribute of the entry, and then call .save again to persist the change.

Like how GET requests are used for reading entries from the database, and POST requests are used for creating new entries in the database, convention dictates that you should use PUT requests to update entries in the database.

Here’s what a PUT endpoint to update a Person would look like:

@PutMapping("/plants/{id}") public Person updatePerson(@PathVariable("id") Integer id, @RequestBody Person p) { Optional<Person> personToUpdateOptional = this.personRepository.findById(id); if (!personToUpdateOptional.isPresent()) { return null; } // Since isPresent() was true, we can .get() the Person object out of the Optional Person personToUpdate = personToUpdateOptional.get(); if (p.getName() != null) { personToUpdate.setName(p.getName()); } if (p.getAge() != null) { personToUpdate.setAge(p.getAge()); } if (p.getEyeColor() != null) { personToUpdate.setEyeColor(p.getEyeColor()); } Person updatedPerson = this.personRepository.save(personToUpdate); return updatedPerson; }

In this example, the updatePerson method takes an Integer id as path parameter and a Person p as the request body.

The id path parameter is used in the call to this.personRepository.findById to find the Person entry in the PEOPLE table that we wish to update.

We first check if the id existed in the database with the .isPresent() method on the Optional<Person> personToUpdateOptional. If it was not present, that meant the id did NOT exist in the database, so the method terminates early by returning null to the response body.

Otherwise, if .isPresent() was NOT false, we can proceed to .get() the underlying Person object out of the Optional and use it for the rest of the method.

The Person object passed in the request body is used to store the new field values that should be used to update the targeted entry. It does not need to have ALL the fields that a Person has. When Spring Boot (via Jackson) converts the request body to a Person object, it simply sets any fields that are missing to null. Because of this, we are able to use a single endpoint to update any field of the Person. We can use if statements to update a field of the target database entry ONLY IF the corresponding field in the request body object was not null.

Lastly, we call the CrudRepository .save method to persist the changes that we made to the person. We return the output of the .save method (updatedPerson) to the user in the response body, so that they can see how the target entry was updated.

Let’s create a similar PUT endpoint for our plants application.

Instructions

1.

Like you did before, start by creating a method in the PlantController, updatePlant. Don’t add any of the Spring annotations just yet. Your updatePlant method should accept an Integer id and a Plant p. It should return a Plant. Declare this method and have it return null for the time being.

2.

Now, add logic into this method that uses the plantRepository to find the plant with the specified id:

  1. Save it into a variable Optional<Plant> plantToUpdateOptional.
  2. Then, use the .isPresent() and .get() methods on the plantToUpdateOptional to add an if statement that will terminate the method early and return null; if the id could not be found in the database.
  3. Otherwise, your method should store the found Plant in a variable called plantToUpdate. For now, return this plantToUpdate so your code can compile.
3.

Similar to the Person example, use if statements to conditionally check if the fields of p are null, and (if they are not), use the “setter” methods of plantToUpdate to update the fields that have been provided in the request. The fields you should check are: name, quantity, wateringFrequency, and hasFruit.

4.

After all the if statements, add the line that will save our updated plant to the database, and store the output in a variable named updatedPlant. Return the updatedPlant.

5.

Before testing this method, you’ll need to add all the appropriate Spring annotations. Add the annotations that:

  • Make this method the handler for a PUT endpoint at "/plants/{id}"
  • Make the Integer id parameter a path parameter
  • Make the Plant p parameter the request body
6.

Time to test out your new functionality! Use curl to submit a PUT request to update the quantity of the "Calla Lily" plant to 36, and update the wateringFrequency to every 3 days instead of every 4.

To get the id of the "Calla Lilly" that we wish to update, try using your GET /plants endpoint first!

Sign up to start coding

By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.
Already have an account?