Skip to content

[chapter4end] Issue: PUT endpoint fails when JSON body doesn't include id field #5

@ghtndl

Description

@ghtndl

Problem Description

The PUT /coffees/{id} endpoint throws a JpaSystemException when the request body doesn't include the id field, even though the id is provided in the URL path.

Error Message

org.hibernate.id.IdentifierGenerationException: Identifier of entity 'com.thehecklers.sbur_rest_demo.Coffee' must be manually assigned before calling 'persist()'

Root Cause

The issue occurs because:

  1. The @PathVariable String id parameter extracts the ID from the URL path (e.g., /coffees/1111id = "1111").
  2. The @RequestBody Coffee coffee object is created by Jackson from the JSON body only.
  3. These are two separate variables/objects — the URL path parameter and the request body object are independent.
  4. When the JSON body doesn't include an id field (e.g., {"name": "byecoffee"}), Jackson creates a Coffee object using the default constructor, leaving the id field as null.
  5. Hibernate/JPA requires the id field to be set before calling save(), causing the exception.

Steps to Reproduce

  1. Send a PUT request to /coffees/1111 with the following JSON body:
    {
      "name": "byecoffee"
    }
  2. The request fails with a 500 Internal Server Error.

Expected Behavior

The endpoint should use the id from the URL path to update or create the entity, regardless of whether the JSON body includes the id field.

Suggested Fix

Add coffee.setId(id); before calling coffeeRepository.save(coffee) to ensure the entity has the correct ID from the URL path:

@PutMapping("/{id}")
ResponseEntity<Coffee> putCoffee(@PathVariable String id,
                                 @RequestBody Coffee coffee) {
    coffee.setId(id);  // Add this line
    return (!coffeeRepository.existsById(id))
            ? new ResponseEntity<>(coffeeRepository.save(coffee),
            HttpStatus.CREATED)
            : new ResponseEntity<>(coffeeRepository.save(coffee),
            HttpStatus.OK);
}

Additional Context

  • Spring Boot version: 3.5.8
  • Using JPA with Hibernate
  • The Coffee entity uses @Id annotation without auto-generation, requiring manual ID assignment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions