我使用HTTP PATCH方法编辑JPA实体。由于这是PATCH,因此只编辑那些未设置为null的字段。在DTO和实体之间仅映射非空字段的最佳方法是什么?给定的实体可能有多个字段 - 比方说20个或更多,所以我不想这样做:
if(dto.getFoo() != null) {
entity.setFoo(dto.getFoo);
}
这种映射有没有智能机制?
我使用的是springboot:1.5.6.RELEASE
答案 0 :(得分:1)
Blaze-Persistence可更新的实体视图将是您正在寻找的更智能的解决方案;) 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
刷新模式时执行的更新查询将仅包含具有非空值的属性的set子句。 DTO看起来像这样
@EntityView(MyEntity.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface MyDto {
@IdMapping Integer getId();
String getFoo();
void setFoo(String foo);
}
如果没有脏东西,它甚至不会执行查询。