Cómo distinguir entre valores nulos y no proporcionados para actualizaciones parciales en Spring Rest Controller

Estoy tratando de distinguir entre valores nulos y valores no proporcionados cuando actualizo parcialmente una entidad con el método de solicitud PUT en Spring Rest Controller.

Considere la siguiente entidad, como ejemplo:

@Entity
private class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /* let's assume the following attributes may be null */
    private String firstName;
    private String lastName;

    /* getters and setters ... */
}

El repositorio My Person (Spring Data):

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
}

El DTO que uso:

private class PersonDTO {
    private String firstName;
    private String lastName;

    /* getters and setters ... */
}

Mi Spring RestController:

@RestController
@RequestMapping("/api/people")
public class PersonController {

    @Autowired
    private PersonRepository people;

    @Transactional
    @RequestMapping(path = "/{personId}", method = RequestMethod.PUT)
    public ResponseEntity<?> update(
            @PathVariable String personId,
            @RequestBody PersonDTO dto) {

        // get the entity by ID
        Person p = people.findOne(personId); // we assume it exists

        // update ONLY entity attributes that have been defined
        if(/* dto.getFirstName is defined */)
            p.setFirstName = dto.getFirstName;

        if(/* dto.getLastName is defined */)
            p.setLastName = dto.getLastName;

        return ResponseEntity.ok(p);
    }
}

Solicitud con propiedad faltante

{"firstName": "John"}

Comportamiento esperado: actualizaciónfirstName= "John" (salirlastName sin alterar).

Solicitud con propiedad nula

{"firstName": "John", "lastName": null}

Comportamiento esperado: actualizaciónfirstName="John" y establecerlastName=null.

No puedo distinguir entre estos dos casos, ya quelastName en el DTO siempre se establece ennull por Jackson

Nota: Sé que las mejores prácticas REST (RFC 6902) recomiendan usar PATCH en lugar de PUT para actualizaciones parciales, pero en mi caso particular necesito usar PUT.

Respuestas a la pregunta(4)

Su respuesta a la pregunta