Реализация RequestMethod.PATCH в Spring RestController

Я создаю Rest API для базы данных MongoDB, используя MongoRepository. Я хочу создать конечную точку, которая использует «RequestMethod.PATCH» и реализует функциональность «PATCH»: дельта-обновление с полями, предоставленными в @RequestBody.

Функциональность, которую я хочу, уже существует в «Spring Data Rest» с использованием аннотации «@RepositoryRestResource» в моем классе Repository, как описано здесь https://spring.io/guides/gs/accessing-data-rest/

Но я не хочу так раскрывать свой класс репозитория. Мне нравится классическая линия Controller->Service->Repository. Мой контроллер выглядит так:

@RestController
public class ActivitiesController {

    @Autowired
    ActivitiesService activitiesService;

    @RequestMapping(value="activities", method=RequestMethod.PATCH)
    public ActivityModel updateActivity(
            @RequestBody ActivityModel activityModel
    ){
        //Input ActivityModel will only have subset of fields that have been changed, aka the delta
        return activitiesService.update(activityModel);
    }

    @RequestMapping(value="activities", method=RequestMethod.PUT)
    public ActivityModel updateActivity(
            @RequestBody ActivityModel activityModel
    ){
        //Input ActivityModel will have all fields populated
        return activitiesService.save(activityModel);
    }

}

И мой репозиторий здесь:

@Repository
public interface ActivitiesRepo extends MongoRepository<ActivityModel, String> {
    //out of the box implementation
}

Моя проблема в том, что, насколько я могу судить, MongoRepository не предоставляет дельта-обновления из коробки, как это делает Spring Data Rest. Как я могу реализовать эту функциональность на уровне службы здесь?:

@Service
public class ActivitiesService {

    @Autowired
    ActivitiesRepo activitiesRepo;

    public ActivityModel update(ActivityModel activityModel){
        //delta update implementation, aka PATCH implementation
    }

    //method that should only be used with RequestMethod.PUT
    public ActivityModel save(ActivityModel activityModel){
        return activitiesRepo.save(activityModel);
    }

}

Что вы думаете об этом решении для ручной реализации PATCH:

public class ModelUtil {
    public static <T> Object update(Object origModel, Object dirtyModel, Class<T> clazz){

        ObjectMapper m = new ObjectMapper();
        HashMap<String, Object> origModelAsMap = m.convertValue(origModel, new TypeReference<Map<String, Object>>() {});
        HashMap<String, Object> dirtyModelAsMap = m.convertValue(dirtyModel, new TypeReference<Map<String, Object>>() {});

        dirtyModelAsMap.forEach((k, v)-> {
            origModelAsMap.put(k, v);
        });

        return m.convertValue(origModelAsMap, clazz);
    }
}

person Silas    schedule 01.02.2017    source источник
comment
Проблема в том, что Spring MVC не поддерживает патч: см. stackoverflow.com/a/39424421/1356423.   -  person Alan Hay    schedule 01.02.2017
comment
Да, но есть ли какие-либо предложения о том, как я могу элегантно реализовать это в компоненте Service?   -  person Silas    schedule 02.02.2017
comment
Не легко. Например, как вы будете отличать поля, явно обнуленные в запросе PATCH, от полей, отсутствующих в запросе?   -  person Alan Hay    schedule 02.02.2017
comment
@AlanHay, что вы думаете о новом коде, который я добавил выше для реализации обновления типа PATCH?   -  person Silas    schedule 02.02.2017