当实体使用json解析时,hibernate会部分更新 [英] hibernate partially update when entity parsed with json

查看:129
本文介绍了当实体使用json解析时,hibernate会部分更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a pretty simple mysql record like this:

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

这是它的休眠实体;没什么花哨的

And here is its hibernate entity; nothing fancy

@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字符串是这样的:

For convenience, I use Gson to parse the entity from json string which front-end passed in.
The json string for the record is like this:

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

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

then userEntity will be parsed from the json String:

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

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

I can insert or update the user with Session.save(userEntity) and Session.update(userEntity).

如果每个字段都包含在json字符串中,那么事情似乎按预期进行. 但是,当某些字段(例如password)被省略时:

If every field is contained in the json string, then things seemed goes as expected. But when some field, such as password is omitted:

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

表示我应该进行部分更新,并保留省略的字段不被修改,这是错误的.因为 解析过程会将password设置为Null.并将其更新到数据库.

which indicated that I should make a partial update and leave the omitted field not modified, things went wrong. Because the parsing procedure will set password to Null. and update it to the database.

那么,在这种情况下,是否有解决方案来部分更新记录?

So, is there a solution to partially update the record in this case?

最后一个选择是遍历每个字段并逐一设置字段;除此之外呢?

Going through every field and setting fields one by one will be the last option; anything other than that?

谢谢.

推荐答案

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

1,Suppose you can deserialized srcUserEntity by:

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

2,您可以利用spring的BeanUtil的复制属性方法.

2, You can leverage spring's BeanUtil's copy properties method.

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

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

3, In your Dao layer, just fetch the model from Database first, then update the properties needs to be updated only, lastly update. Refer to codes as below:

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()方法,请参阅[

4, for getNullPropertyNames() method, please refer to [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))
}

这篇关于当实体使用json解析时,hibernate会部分更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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