JPA:仅更新特定字段 [英] JPA: update only specific fields

查看:143
本文介绍了JPA:仅更新特定字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用 Spring Data JPA 中的 save 方法更新实体对象的仅某些字段 >?

Is there a way for updating only some fields of an entity object using the method save from Spring Data JPA?

例如我有一个像这样的JPA实体:

For example I have a JPA entity like this:

@Entity
public class User {

  @Id
  private Long id;

  @NotNull
  private String login;

  @Id
  private String name;

  // getter / setter
  // ...
}

使用其CRUD仓库:

public interface UserRepository extends CrudRepository<User, Long> { }

Spring MVC 中我有一个控制器获得用户更新对象:

In Spring MVC I have a controller that get an User object for update it:

@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {

   // Assuming that user have its id and it is already stored in the database,
   // and user.login is null since I don't want to change it,
   // while user.name have the new value

   // I would update only its name while the login value should keep the value 
   // in the database
   userRepository.save(user);

   // ...
}

我知道我可以使用 findOne 加载用户,然后更改其名称并使用 save 更新它...但是如果我有100个字段,我想要更新其中50个,这可能会让每个值变得非常烦人..

I know that I could load the user using findOne, then change its name and update it using save... But if I have 100 fields and I want to update 50 of them it could be very annoying change each value..

有没有办法说出类似跳过所有null保存对象时的值

推荐答案

我有同样的问题,正如M. Deinum指出的那样,答案是否定的,你不能使用保存。主要问题是Spring Data不知道如何处理null。空值是否未设置或是否设置因为需要删除?

I had the same question and as M. Deinum points out, the answer is no, you can't use save. The main problem being that Spring Data wouldn't know what to do with nulls. Is the null value not set or is it set because it needs to be deleted?

现在从你的问题判断,我认为你也有同样的想法,哪个保存将允许我避免手动设置所有更改的值。

Now judging from you question, I assume you also had the same thought that I had, which was that save would allow me to avoid manually setting all the changed values.

那么可以避免所有的manuel映射吗?好吧,如果你选择遵守惯例,nulls总是意味着'not set'并且你有原始的模型id,那么是的。
您可以使用Springs BeanUtils避免任何映射。

So is it possible to avoid all the manuel mapping then? Well, if you choose to adhere to the convention that nulls always means 'not set' and you have the original model id, then yes. You can avoid any mapping yourself by using Springs BeanUtils.

您可以执行以下操作:


  1. 读取现有对象

  2. 使用BeanUtils复制值

  3. 保存对象

现在,Spring的BeanUtils实际上不支持不复制空值,因此它将覆盖现有模型对象上未设置为null的任何值。幸运的是,这里有一个解决方案:

Now, Spring's BeanUtils actual doesn't support not copying null values, so it will overwrite any values not set with null on the exiting model object. Luckily, there is a solution here:

如何使用springframework BeanUtils copyProperties忽略空值?

所以把它们放在一起你最终会得到它们类似这样的事情

So putting it all together you would end up with something like this

@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {

   User existing = userRepository.read(user.getId());
   copyNonNullProperties(user, existing);
   userRepository.save(existing);

   // ...
}

public static void copyNonNullProperties(Object src, Object target) {
    BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}

public static String[] getNullPropertyNames (Object source) {
    final BeanWrapper src = new BeanWrapperImpl(source);
    java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

    Set<String> emptyNames = new HashSet<String>();
    for(java.beans.PropertyDescriptor pd : pds) {
        Object srcValue = src.getPropertyValue(pd.getName());
        if (srcValue == null) emptyNames.add(pd.getName());
    }
    String[] result = new String[emptyNames.size()];
    return emptyNames.toArray(result);
}

这篇关于JPA:仅更新特定字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆