Как определить какие поля были изменены при использовании конвертации JSON в POJO?
Имеется веб-сервис, который принимает JSON payload (для PUT метода).
Для конвертации JSON в Java объект используется Jackson.
Есть задача обновлять только те поля, которые присутствуют в JSON (новые значения могут иметь значение null).
Проблема в том, что после конвертации JSON в Java объект, все поля, которые не присутствовали в JSON, имеют значение null и я не могу определить почему они null: потому что их не было в JSON (и я не хочу их обновлять), или потому что они там были с значением null (и я хочу их обновить).
Насколько я понимаю, если поле присутствовало в JSON и у него там было значение null, то Jackson вызовет для этого поля сеттер.
Каким образом я могу узнать какие сеттеры у объекта были вызваны, а какие нет?
Или для подобной задачи есть другие способы решения? На мой взгляд, это достаточно распространенная проблема.
Влад Мистецкий: не так понял вопрос, извиняюсь. Но тогда вам нет смысла не обновлять значение поля: в любом случае локальная БД будет хранить все поля объекта со значениями по умолчанию, теми самыми null (если нет, то вам нужно делать alter table и это уже версионность объектов). Если у вас было значение, а в пришедшем json его нет (и, соответственно, в объекте null), то и перезаписывайте этот null, роли особой это не играет.
LeEnot: Проблема в том, что если в БД у меня было значение для поля (не null) и клиент прислал JSON без этого поля, то я не хочу его затереть в null. Но если клиент мне прислал это поле в JSON: {a:null}, то я хочу затереть его в null.
Влад Мистецкий: вам стоит качественнее продумать юз кейс. Если обновляют несколько полей, присылайте все остальные такими как они и были. Или же тогда игнорируйте null. Или же используйте ID объектов в БД для подхвата прошлых значений.
Artem Vereschaka: В этом и заключается основная проблема. Я не хочу заставлять клиента отправлять ВСЕ поля со старыми значениями, потому что
а) перед апдейтом он обязательно должен сделать GET, что не всегда необходимо
б) гоняем кучу лишних данных
в) это КРАЙНЕ небезопасно, если в клиентском приложении есть ошибка (например не добавили новое поле в модель) и оно не пришлет это значение на сервер - я это значение на сервере обнулю, чего я делать не хочу
Игнорировать null не получится, так как не для всех типов реализуемо (например как клиенту обнулить Integer поле без null?)
Влад Мистецкий: что значит - "не хочет обновлять вообще"? А прислать текущее значение и перезаписать его нельзя? Или вы трафик экономите? Тогда можете подсовывать Jackson'у CustomSerializer, в котором задавать полям в объекте на обнуление какое-то специальное значение.
Ну и да, если вы что-то собираетесь изменять, вам нужно именно это задавать ЯВНО. Т.е. признаком обнуления должно быть не отсутствие поля, а специальное значение. Так вы ничего не сломаете.
Привет! Если это нужно для небольшого количества объектов, то можно написать кастомный сериалайзер в jackson, и самому определить политику работы с каждым полем.
Или второй вариант. Можно написать сериалайзер для конкретного типа поля. Например для String. Чтобы он сеттил какое-нибудь значение по умолчанию, если не находил такого в json.