Каков наилучший способ сопоставления ненулевых полей между сущностью и DTO?
Я использую метод HTTP PATCH для редактирования объекта JPA. Поскольку это PATCH, будут редактироваться только те поля, для которых не установлено значение NULL. Каков наилучший способ отображения только ненулевых полей между DTO и сущностью? У данного объекта может быть несколько полей - скажем, 20 или более, поэтому я не хочу делать это следующим образом:
if(dto.getFoo() != null) {
entity.setFoo(dto.getFoo);
}
Есть ли какой-нибудь умный механизм для такого отображения?
Я использую Springboot: 1.5.6.RELEASE
1 ответ
Blaze-Persistence Updatable Entity Views будет самым разумным решением, которое вы ищете;) Blaze-Persistence - библиотека поверх JPA, над которой я работаю. Ваш вариант использования уже должен быть поддержан, хотя у меня пока не очень хорошая интеграция с Spring WebMvc, поэтому вам придется пока что-то сделать самостоятельно. У меня есть кое-что для этого, хотя это просто вопрос времени и заинтересованных сторон, пока интеграция не будет гладкой.
Обновляемые представления сущностей позволяют отображать подмножество сущностей, а также сбрасывать только это подмножество. Благодаря использованию грязного слежения, он точно знает, что изменилось, что позволяет производить мелкозернистую промывку.
Поэтому идея поддержки PATCH заключается в том, чтобы просто получить пустую ссылку по id для объекта. Быть пустым означает, что у него нет данных, то есть все нулевые значения. Грязное отслеживание предполагает, что начальное состояние все равно нулю. Вы можете просто отобразить полезную нагрузку запроса на этот объект, если значение равно нулю, оно не распознает его как измененное, поэтому игнорирует его. Если было задано что-либо, отличное от NULL, оно определяет, что такое поле является грязным и при сбросе только сбрасывает грязные значения.
Я сам еще не пробовал, но ты мог бы сделать что-то подобное
// Create reference for the id, the object is empty i.e. all null except for the id
MyDto dto = entityViewManager.getReference(MyDto.class, someId);
// Map the payload on the DTO which will call setFoo(null) but that's ok, because that isn't considered being dirty
jsonMapper.map(requestPayload, dto);
// Flush dirty changes i.e. non-null values
entityViewManager.update(entityManager, dto);
Выполненный запрос на обновление при использовании PARTIAL
Режим сброса будет содержать только установленные предложения для свойств с ненулевыми значениями. DTO будет выглядеть так
@EntityView(MyEntity.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface MyDto {
@IdMapping Integer getId();
String getFoo();
void setFoo(String foo);
}
Если нет ничего грязного, он даже не выполнит запрос.