I'm using HTTP PATCH method to edit JPA entity. Since this is PATCH, only those fields will be edited that are not set to null. What is the best way of mapping only non-null fields between the DTO and the entity? The given entity may have multiple fields - say 20 or more so I don't wan to do it this way:
if(dto.getFoo() != null) {
entity.setFoo(dto.getFoo);
}
Is there any smart mechanism for such mapping?
I'm using springboot: 1.5.6.RELEASE
Blaze-Persistence Updatable Entity Views would be the smarter solution you are looking for ;) Blaze-Persistence is a library on top of JPA that I work on. Your use case should be supported already, though I don't have a very good integration for Spring WebMvc yet, so you will have to do some plumbing yourself for now. I have something in mind for this though, it's just a matter of time and interested parties until the integration will be smoother.
Updatable entity views allow to map a subset of entities and also only flush that subset back. Thanks to the use of dirty tracking, it knows exactly what changed, allowing for fine grained flushing.
So the idea for PATCH support is to just get an empty reference by id for an object. Being empty means, that it has no data i.e. all null values. The dirty tracking assumes the initial state is all null then. You can simply map a request payload onto this object, if a value is null, it won't recognize it as being changed, thus ignore it. If anything non-null was set, it determines that such a field is dirty and on flush, only flushes dirty values.
I haven't tried it myself yet, but you could do something like this
// 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);
The executed update query when using the PARTIAL
flush mode will only contain set clauses for properties with non-null values. The DTO would look like this
@EntityView(MyEntity.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface MyDto {
@IdMapping Integer getId();
String getFoo();
void setFoo(String foo);
}
If nothing is dirty, it won't even execute a query.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With