Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring数据Rest:在更新方法上限制发送值_Java_Spring_Spring Boot_Spring Data Jpa_Spring Data Rest - Fatal编程技术网

Java Spring数据Rest:在更新方法上限制发送值

Java Spring数据Rest:在更新方法上限制发送值,java,spring,spring-boot,spring-data-jpa,spring-data-rest,Java,Spring,Spring Boot,Spring Data Jpa,Spring Data Rest,我已经使用SpringDataREST通过项目实现了。我正在尝试更新表中的现有记录。但当我试图通过请求只发送几个字段而不是所有字段(实体类中的字段)时,Spring数据会认为我发送的是null/空值。最后,当我去查看数据库时,我没有通过请求发送的字段将被null/empty值覆盖。所以我的理解是,即使我不发送这些值,SpringDataREST也会在实体类中看到它们,并将这些值作为null/empty发送。我这里的问题是,有没有一种方法可以在执行更新时禁用我没有通过请求发送的字段。谢谢你的帮助

我已经使用SpringDataREST通过项目实现了。我正在尝试更新表中的现有记录。但当我试图通过请求只发送几个字段而不是所有字段(实体类中的字段)时,Spring数据会认为我发送的是null/空值。最后,当我去查看数据库时,我没有通过请求发送的字段将被null/empty值覆盖。所以我的理解是,即使我不发送这些值,SpringDataREST也会在实体类中看到它们,并将这些值作为null/empty发送。我这里的问题是,有没有一种方法可以在执行更新时禁用我没有通过请求发送的字段。谢谢你的帮助


更新:我使用的是PUT方法。读了评论后,我把它改成了补丁,现在它工作得很好。感谢所有帮助

在更新之前,使用jpa方法
findById
从数据库加载对象调用
target
。 然后将所有非空字段从
要更新的对象
复制到
目标
,最后保存
目标
对象

这是一个代码示例:

public void update(Object objectWantToUpdate) {

    Object target = repository.findById(objectWantToUpdate.getId());
    copyNonNullProperties(objectWantToUpdate, target);

    repository.save(target);
}

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

public String[] getNullPropertyNames (Object source) {

    final BeanWrapper src = new BeanWrapperImpl(source);
    PropertyDescriptor[] propDesList = src.getPropertyDescriptors();

    Set<String> emptyNames = new HashSet<String>();

    for(PropertyDescriptor propDesc : propDesList) {
        Object srcValue = src.getPropertyValue(propDesc.getName());

        if (srcValue == null) {
            emptyNames.add(propDesc.getName());
        }
    }

    String[] result = new String[emptyNames.size()];
    return emptyNames.toArray(result);
}
公共无效更新(对象对象对象更新){
Object target=repository.findById(objectWantToUpdate.getId());
copyNonNullProperties(ObjectWantUpdate,目标);
保存(目标);
}
公共void copyNonNullProperties(对象源、对象目标){
copyProperties(源、目标、getNullPropertyNames(源));
}
公共字符串[]getNullPropertyNames(对象源){
最终BeanRapper src=新BeanRapperImpl(来源);
PropertyDescriptor[]propDesList=src.getPropertyDescriptors();
Set emptyNames=new HashSet();
对于(PropertyDescriptor propDesc:propDesList){
对象srcValue=src.getPropertyValue(propDesc.getName());
if(srcValue==null){
add(propDesc.getName());
}
}
字符串[]结果=新字符串[emptyNames.size()];
返回emptyNames.toArray(结果);
}

您可以编写只更新特定字段的自定义更新查询:

@Override
public void saveManager(Manager manager) {  
    Query query = sessionFactory.getCurrentSession().createQuery("update Manager set username = :username, password = :password where id = :id");
    query.setParameter("username", manager.getUsername());
    query.setParameter("password", manager.getPassword());
    query.setParameter("id", manager.getId());
    query.executeUpdate();
}

正如一些评论所指出的,使用补丁而不是PUT解决了这个问题。感谢所有的投入。以下内容来自Spring数据Rest文档:

“PUT方法用提供的请求正文替换目标资源的状态

补丁方法与PUT方法类似,但部分更新了资源状态。”


另外,我喜欢@Tran-qooc-Vu-answer,但暂时不实现它,因为我不必使用自定义控制器。如果在更新实体时涉及一些逻辑(例如:验证),我赞成使用自定义控制器。

而不是使用put use patch方法,这与spring数据无关;这就是JPA/Hibernate的工作原理。如果试图通过传递实体进行更新,则所有未填充的字段都将被视为null,因此更新将为null。您应该使用HQL o JPQL,而不是使用什么HTTP方法来更新您的实体?PUT或PATCH?@Cerp0这取决于您的需要,PUT的主要目标是将整个资源“放到”某个地方(实体的所有字段),而PATCH只发送您需要“修补”的值(例如实体的一个或两个字段)@angeloimmedita,而JPA/Hibernate也可能使用这种语义,考虑到通过
PUT
进行的更新,实际上是通过
PUT
接收的有效负载应该替换当前表示。所以Spring只是按照规范的意图来做谢谢@Tran qooc Vu,我喜欢你的答案。现在我不使用这个解决方案,因为它涉及添加一个新的自定义控制器。我现在要用补丁而不是PUT。但是如果我看到自定义控制器的使用,我可能会回到这个问题上来。