我正在尝试基于以下内容实现Manager实体的部分更新:
实体
public class Manager {
private int id;
private String firstname;
private String lastname;
private String username;
private String password;
// getters and setters omitted
}
控制器中的SaveManager方法
@RequestMapping(value = "/save", method = RequestMethod.PATCH)
public @ResponseBody void saveManager(@RequestBody Manager manager){
managerService.saveManager(manager);
}
在DAO实现中保存对象管理器。
@Override
public void saveManager(Manager manager) {
sessionFactory.getCurrentSession().saveOrUpdate(manager);
}
当我保存对象时,用户名和密码已正确更改,但其他值为空。
因此,我需要做的是更新用户名和密码,并保留所有剩余数据。
5条答案
按热度按时间7cwmlq891#
如果您真的在使用补丁,那么您应该使用RequestMethod.PATCH,而不是RequestMethod.POST。
补丁Map应包含可用于检索要打补丁的管理器对象的ID。此外,它应该只包括您想要更改的字段。在您的示例中,您发送的是整个实体,因此您无法识别实际正在更改的字段(Empty是指不使用该字段,还是实际上将其值更改为Empty)。
也许这样的实现就是您想要的?
更新
我想提供这篇文章的更新,因为现在有一个简化修补过程的项目。
神器是
在OP中修补Manager对象的实现如下所示:
控制器
服务
补丁请求遵循RFC 6092中的规范,因此这是一个真正的补丁实现。详情可在here中找到
inkz8wg92#
有了这个,您就可以修补您的更改
您必须扩展
BeanUtilsBean
以实现非空值行为的复制。最后,将NullAwareBeanUtilsBean标记为
@Component
或
将
NullAwareBeanUtilsBean
注册为Beanej83mcc03#
首先,您需要知道您是在执行插入操作还是更新操作。INSERT很简单。在更新时,使用get()检索实体。然后更新任何字段。在事务结束时,Hibernate将刷新更改并提交。
fhg3lkii4#
您可以编写仅更新特定字段的自定义更新查询:
igetnqfo5#
ObjectMapper.updateValue
提供了将实体与从dto到的值部分Map所需的全部内容。作为补充,您可以在此处使用两种方法之一:Map<String, Object> fields
或String json
,因此您的服务方法可能如下所示:作为Lane Maxwell回答的第二个解决方案和补充,您可以使用
Reflection
仅Map已发送的值Map中存在的属性,因此您的服务方法可能如下所示:第二个解决方案允许您在Map过程中插入一些额外的业务逻辑,可能是转换或计算等。
此外,与按名称查找反射字段
Field field = ReflectionUtils.findField(Foo.class, k);
并使其可访问不同,查找属性的setter实际上调用setter方法,该方法可能包含要执行的额外逻辑,并防止将值设置为私有属性。