如何仅在休眠中更新JSON定义的属性 [英] How to only update JSON defined properties in hibernate

查看:120
本文介绍了如何仅在休眠中更新JSON定义的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个SpringBoot/Angular 8应用程序,并且在尝试更新解耦的前端/后端对象时遇到一些问题.当我发送包含角度模型的json发布请求时,@JsonIgnore'或其他缺少的值将更新为null而不是被忽略.

I'm creating a SpringBoot/Angular 8 Application and am having some issues when attempting to update the decoupled frontend/backend objects. When I send a json post request containing the angular model, the @JsonIgnore'd or otherwise missing values are updated to null instead of being ignored.

这个堆栈溢出问题密切相关,并且推荐的解决方案确实起作用,但是它破坏/绕过了一堆Jackson/Hibernate注释(例如@Inheritance(strategy=InheritanceType.JOINED)@Transient),所以我想寻找替代方法可能的解决方案: 使用json解析实体时,hibernate部分更新

This stack overflow question is closely related, and the recommended solution does work, but it breaks/bypasses a bunch of the Jackson/Hibernate annotations (e.g. @Inheritance(strategy=InheritanceType.JOINED) and @Transient), so I would like to look for alternative solutions if possible: hibernate partially update when entity parsed with json

@Entity
@Table(name = "users")
@DynamicUpdate
public class User implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String a;

    @Column
    private String b;

    @Column (nullable = false)
    @JsonIgnore
    private String c;

   // standard getters and setters
}

示例Java Rest API

@RequestMapping(value = "/api/user", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<User> saveOrUpdate(@RequestBody User user, BindingResult result, HttpServletRequest request) {
    if(user.getId()!=null){
        user=ws.update(user);
    }else{
        user=us.create(user);
    }
    return new ResponseEntity<>(user,HttpStatus.OK);
}

示例角度服务方法

saveUser(user:User): Observable<User>{
    const body = JSON.stringify(user);
    return this.http.post<User>('/api/user', body).pipe(map( response => response));
}

现有数据库模型:

{ 
  id:1,
  a:"some value a"
  b:"some value b"
  c:"some value c"
}

角柱体:

{ 
  id:1,
  a:"some value a2"
  b:"some value b2"
}

预期的休眠查询:

update users set a=?,b=? where id=?

update users set a=?,b=?,c=? where id=? 在这种情况下,C为空值.

update users set a=?,b=?,c=? where id=? C, in this case, is a null value.

推荐答案

不要对从angular发送的对象使用update方法,因为它会替换数据库中的整个原始对象.在更新的情况下,我建议您从数据库中检索存在的对象(例如,使用spring-data仓库的findOne方法),然后仅复制修改后的字段而忽略空值.您可以使用Apache commons库中的BeanUtils copyProperties方法.原始方法在复制时不会忽略null值,因此您必须稍微重写一下:

Don't use update method with the object sent from angular as it replaces the whole original object from the database. What i suggest to you in case of update is to retrieve the existent object from database (for example with spring-data repository findOne method), then copy only modified fields ignoring null values. You can use BeanUtils copyProperties method from Apache commons library. The original method doesn't ignore null values when copying, so you have to override it a little :

public class NullAwareBeanUtilsBean extends BeanUtilsBean {
    @Override
    public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException {
        if (value == null)
            return;
        super.copyProperty(dest, name, value);
    }
}

此测试再现了您想要做的事情:

This test reproduces what you want to do :

要更新的类:

public class A {

    private String foo;

    private String bar;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }
}

测试类:

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.zpavel.utils.NullAwareBeanUtilsBean;

public class MyTest {

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        A a1 = new A();
        a1.setFoo("foo");
        A a2 = new A();
        a2.setBar("bar");
        BeanUtilsBean notNull = new NullAwareBeanUtilsBean();
        notNull.copyProperties(a2, a1);
        System.out.println(ToStringBuilder.reflectionToString(a2));
    }
}

这篇关于如何仅在休眠中更新JSON定义的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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