有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当使用json解析实体时,java hibernate会部分更新

我有一个非常简单的mysql记录,如下所示:

+------+-------+-----------+
| id   |  name | password  |
+------+-------+-----------+
| 1    | John  | d0c91f13f |
+------+-------+-----------+
 ...      ...     ...

这是它的冬眠实体;没什么特别的

@Entity
@Table(name = "user", schema = "", catalog = "trade")
public class UserEntity{
     private long id;
     private String name;
     private String password;

     @Id
     @Column(name = "id")
     public long getId(){
          return id;
     }
     public void setId(long id){
          this.id = id;
     }

     @Column(name = "name")
     public String getName(){
          return name;
     }
     public void setName(String name){
          this.name = name;
     }

     @Column(name = "password")
     public String getPasswrod(){
          return password;
     }
     public void setPassword(String password){
          this.password = password;
     }
}

为了方便起见,我使用Gson从前端传入的json字符串解析实体
记录的json字符串如下所示:

{"id":1, "name":"John", "password":"d0c91f13f"}

然后将从json字符串中解析userEntity:

UserEntity userEntity = gson.fromJson(userJson, UserEntity.class);

我可以用Session.save(userEntity)Session.update(userEntity)插入或更新用户

如果每个字段都包含在json字符串中,那么事情看起来就像预期的那样。 但是当某些字段,例如password被省略时:

{"id":1, "name":"John Smith"}

这意味着我应该进行部分更新,并保留省略的字段不进行修改,结果出了问题。因为 解析过程将password设置为空。并将其更新到数据库中

那么,在这种情况下,有没有办法部分更新记录

最后一个选项是遍历每个字段并逐个设置字段;还有别的吗

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    1.假设您可以通过以下方式反序列化srcUserEntity:

    UserEntity srcUserEntity = gson.fromJson(userJson, UserEntity.class);
    

    2、可以利用spring的BeanUtil的复制属性方法

    BeanUtils.copyProperties(srcUserEntity, desUserEntity, SpringBeanUtil.getNullPropertyNames(srcUserEntity));
    

    3.在Dao层中,只需先从数据库中获取模型,然后更新只需要更新的属性,最后更新。参考以下代码:

    Session currentSession =  sessionFactory.getCurrentSession();
    UserEntity modelInDB = (UserEntity)currentSession.get(UserEntity.class, user.getId());
    //Set properties that needs to update in DB, ignore others are null.
    BeanUtils.copyProperties(productStatusModelForPatch, modelInDB, SpringBeanUtil.getNullPropertyNames(productStatusModelForPatch));
    currentSession.update(modelInDB);
    

    4.关于getNullPropertyNames()方法,请参考[How to ignore null values using springframework BeanUtils copyProperties? (Solved)

    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); 
    }
    
    
    // then use Spring BeanUtils to copy and ignore null
    public static void myCopyProperties(Object, src, Object target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src))
    }