Java 如何使用SpringMVC忽略DTO对象中缺少的属性?
我们正在使用Java 如何使用SpringMVC忽略DTO对象中缺少的属性?,java,hibernate,spring-mvc,dto,Java,Hibernate,Spring Mvc,Dto,我们正在使用springmvc4 假设我有一个名为Customer的实体。该实体具有多个属性,其中一些属性允许空值,而另一些属性不允许空值 我们还使用一个DTO对象(CustomerDTO),该对象通过@RequestBody从远程客户端传递到我们的@RestController) 这是我的问题。假设用户通过PUT传入以下内容: { "id": 123, "name": "ACME", "desc": "Blah" } 一切都很好。但如果用户只想更新名称,则会传入: {
springmvc4
假设我有一个名为Customer
的实体。该实体具有多个属性,其中一些属性允许空值,而另一些属性不允许空值
我们还使用一个DTO
对象(CustomerDTO
),该对象通过@RequestBody
从远程客户端传递到我们的@RestController
)
这是我的问题。假设用户通过PUT
传入以下内容:
{
"id": 123,
"name": "ACME",
"desc": "Blah"
}
一切都很好。但如果用户只想更新名称
,则会传入:
{
"id": 123,
"name": "ACME 2"
}
客户现在在desc
中有一个null
,这是允许的
所以我的问题是,如果Spring/Hibernate没有被传递到DTO中,我怎么能让它不在update语句中添加desc
我认为,问题在于Spring将以下内容视为同一件事:
{
...
"desc": null,
...
}
{
...
... <desc omitted>
}
{
...
“desc”:空,
...
}
{
...
...
}
谢谢基于,您似乎基本上有两个可行的选择:
您不需要单独加载实体状态来实现这一点,而是可以利用实体状态库在JPA之上开发DTO,该库还实现了对乐观锁定的支持。 您的用例应该已经得到支持,尽管我还没有一个很好的SpringWebMVC集成,所以您现在必须自己做一些管道工作。我有一些想法,不过,这只是一个时间问题和利益相关方,直到整合将更加顺利 可更新的实体视图允许映射实体的子集,并且只刷新该子集。由于使用了脏跟踪,它准确地知道发生了什么变化,从而允许细粒度的刷新 因此,补丁支持的想法,也就是您在这里想要的,就是只获取一个对象的id的空引用。为空意味着它没有数据,即所有空值。脏跟踪假设初始状态全部为空。您可以简单地将一个请求负载映射到这个对象上,如果一个值为null,它将不会识别它正在被更改,因此忽略它。如果设置了任何非null值,它将确定此类字段为脏字段,并且在刷新时,仅刷新脏值 我自己还没试过,但你可以这样做
// Create reference for the id, the object is empty i.e. all null except for the id
CustomerDTO dto = entityViewManager.getReference(CustomerDTO.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);
@EntityView(Customer.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface CustomerDTO {
@IdMapping Integer getId();
String getName();
void setName(String name);
String getDesc();
void setDesc(String desc);
}
使用PARTIAL
flush模式时执行的更新查询将仅包含具有非空值的属性的set子句。DTO看起来像这样
// Create reference for the id, the object is empty i.e. all null except for the id
CustomerDTO dto = entityViewManager.getReference(CustomerDTO.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);
@EntityView(Customer.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface CustomerDTO {
@IdMapping Integer getId();
String getName();
void setName(String name);
String getDesc();
void setDesc(String desc);
}
如果没有脏东西,它甚至不会执行查询。可能重复的