当前位置: 首页 > 知识库问答 >
问题:

hibernate在使用json解析实体时部分更新

龚博涛
2023-03-14

我有一个非常简单的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);

我可以使用会话插入或更新用户。保存(用户实体)会话。更新(用户实体)

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

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

这表明我应该进行部分更新,并保留省略的字段不进行修改,但出现了问题。因为解析过程将密码设置为Null。并将其更新到数据库中。

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

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

提前谢谢。

共有2个答案

谭灿
2023-03-14

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、对于getNullProperty tyNames()方法,请参考【如何使用springframe BeanUtils的复制属性忽略空值?(已解决)

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))
}
吴伟志
2023-03-14

如果您知道一个特定的条目存在,那么在更新之前获取该条目将用现有的值填充对象,并且您只会更改Json提供的值。这避免了您描述的空更新。

但是,如果条目是新的,那么Json中缺少的任何内容都将作为null传递给数据库。

 类似资料:
  • 问题内容: 我有以下json: 基于的更改。 知道这一点,有没有办法使该字段保持字符串?这个想法是使用调用传递的正确处理程序,然后在其中使用正确的struct 解析字符串。 例: 先感谢您。 问题答案: 使用json.RawMessage获取字段的原始JSON文本: 像这样使用它: 在操场上跑。

  • 问题内容: 我收到一个包含30个字段的JSON,而我的实体是根据此JSON构建的。问题是:不应更新两个字段(两个日期)。 如果使用,两个字段都会更新。 如何避免更新这两个字段? 也许使用criteria.Example? 没有我写大量的HQL,有什么方法可以做到这一点吗? 问题答案: 本文非常详细地解释了您的问题,但我也将在这里进行总结。 如果您永远不想更新这两个字段,则可以将它们标记为: 当你将

  • 是否可以在超类实体中有一个列定义供子类实体使用? 我采用了每子类表层次结构来表示从“超级业务”继承的不同类型的“业务”。因此,每个业务类型在数据库中都有自己的表,并且还有一个通用的“业务”表,其中包含所有业务类型共有的信息。 每个企业都有一个外键列,名为“parent\u id”,它指向相同类型的另一个企业(因此企业可以属于相同类型的其他企业)。这意味着我的每个业务类型类都有自己的“parent”

  • 问题内容: 我使用Hibernate 4和Spring 3。 我有两个实体。 图书实体 和作者实体 和JSON取决于pom.xml 我的根上下文在这里- … servlet-context.xml 控制器。 在我的DAO中找到findAll: 在调试中,我看到该方法返回2条记录,但是Spring无法将结果转换为JSON并返回406 HTTP错误。怎么了? 我附上我在调试中看到的图像。- http:

  • 在我的Android项目中,我使用了reverfit2作为API调用和GSON作为转换器。将json转换为POJO并遵循在同一项目的50+API中也使用的常用方法。 但是,在这种特定的情况下,一些项被解析并分配给变量,而其他项则不是。 如何解决这种部分解析?

  • 本文向大家介绍jQuery解析json数据实例分析,包括了jQuery解析json数据实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析了jQuery解析json数据的方法。分享给大家供大家参考,具体如下: 先来看看我们的Json数据格式: 为了消除乱码问题,我们设置一个过滤器(代码片段) 服务端我用Servlet生成json数据(代码片段)。 页面端JQuery代码: 之前为了省事,