我已经通过的项目中使用Spring的数据休息来实现。我试图做一个表中的现有记录的更新。但是,当我试图仅仅通过我的请求,派几个领域,而不是所有的字段(存在于实体类),Spring的数据休息思考我送空/空值。最后,当我去看看这我不是通过我的请求发送的字段覆盖与空/空值的数据库。所以我的理解是,即使我不发送这些值,弹性数据休息看见他们在实体类和发送这些值作为空/空。在这里我的问题是,有没有办法这样做,我不是通过请求发送UPDATE时禁用的字段。感谢您的任何帮助。
更新:我使用PUT方法。看完评论后,我改变了它来修补其完美的工作了。感谢所有帮助
更新之前,从数据库加载对象,使用JPA方法findById
返回对象调用target
。然后复制,不是空/空从object-want-to-update
到target
,最后保存target
对象的所有领域。
这是代码例如:
public void update(Object objectWantToUpdate) {
Object target = repository.findById(objectWantToUpdate.getId());
copyNonNullProperties(objectWantToUpdate, target);
repository.save(target);
}
public void copyNonNullProperties(Object source, Object target) {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
}
public String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] propDesList = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(PropertyDescriptor propDesc : propDesList) {
Object srcValue = src.getPropertyValue(propDesc.getName());
if (srcValue == null) {
emptyNames.add(propDesc.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
您可以编写自定义更新查询其中仅更新特定字段:
@Override
public void saveManager(Manager manager) {
Query query = sessionFactory.getCurrentSession().createQuery("update Manager set username = :username, password = :password where id = :id");
query.setParameter("username", manager.getUsername());
query.setParameter("password", manager.getPassword());
query.setParameter("id", manager.getId());
query.executeUpdate();
}
正如一些评论指出,使用PATCH而不是PUT解决了问题。感谢所有的输入。以下是从春天数据休息文档:
“PUT方法替换为提供请求正文目标资源的状态。
补丁方法类似于PUT方法,但部分更新资源的状态。”
另外,我喜欢@Tran富国武答案,但不执行它,因为现在我没有使用自定义控制器。如果有一些逻辑:在更新实体参与时(例如验证),我赞成使用自定义控制器。