解决springboot中@DynamicUpdate注解无效的问题

 更新时间:2021年07月05日 14:45:43   作者:小渣笔记  
这篇文章主要介绍了解决springboot中@DynamicUpdate注解无效的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springboot 中 @DynamicUpdate 注解无效解决方案

遇到的问题

项目中使用 jpa,以前没用过,所以踩坑在所难免。

在使用过程中,要更新一条记录的某个字段,更新成功以后,发现整条记录只剩下我更新的那个字段,其他的全部为空了。

瞬间明白,这种更新是全覆盖,针对每个字段 update,实体类没赋值的字段,也直接将空值 set 过去了。

寻求解决方案

这里写图片描述

正在庆幸这么容易就解决,突然发现并没有这么简单。

这里写图片描述

群众的力量是无穷大的,我立刻就明白这个注解为什么无效,原来是搞错了它的用途。

一孔解决方案

如刚才无数个箭头指向的评论所说,用findOne查出原值,然后赋值想要修改的新的字段值。

思路很简单,这里主要贴一下对象复制的代码。将数据库中查出的对象称为target,包含要修改的字段的对象称为source,当然,最后我们save的是修改之后的target

BeanCopyUtil:

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashSet;
import java.util.Set;
/**
 * created by xxx 2018/7/21
 */
public class BeanCopyUtil {
    //source中的非空属性复制到target中
    public static <T> void beanCopy(T source, T target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }
    //source中的非空属性复制到target中,但是忽略指定的属性,也就是说有些属性是不可修改的(个人业务需要)
    public static <T> void beanCopyWithIngore(T source, T target, String... ignoreProperties) {
        String[] pns = getNullAndIgnorePropertyNames(source, ignoreProperties);
        BeanUtils.copyProperties(source, target, pns);
    }
    public static String[] getNullAndIgnorePropertyNames(Object source, String... ignoreProperties) {
        Set<String> emptyNames = getNullPropertyNameSet(source);
        for (String s : ignoreProperties) {
            emptyNames.add(s);
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
    public static String[] getNullPropertyNames(Object source) {
        Set<String> emptyNames = getNullPropertyNameSet(source);
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
    public static Set<String> getNullPropertyNameSet(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        return emptyNames;
    }
}

有了这个方法,在修改的时候就比较方便了,我的做法是在实体类中加一个方法:

    //这里我设置【任务编号】和【创建人】不可修改
    public void copy(Task task) {
        BeanCopyUtil.beanCopyWithIngore(task, this, "taskNum", "createPerson");
    }

然后在service中update方法中调用:

    @Transactional
    public Task updateTask(Task task) {
        try {
            if (task.getId() == null) {
                return null;
            }
            Task saveTask = taskRepository.findOne(task.getId());
            saveTask.copy(task);
            return taskRepository.saveAndFlush(task);
        } catch (Exception e) {
            throw new CustomException(SERVER_ERROR, e);
        }
    }

总结

使用 springboot 时会遇到非常非常多的注解,这确实为开发省去了大量的时间,和很多没有意义的体力劳动。但是在使用注解的时候,一定要弄清楚用途和用法 ,不然明明是用错了,你还会觉得莫名其妙。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springSecurity实现简单的登录功能

    springSecurity实现简单的登录功能

    这篇文章主要为大家详细介绍了springSecurity实现简单的登录功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • 使用maven创建普通项目命令行程序详解

    使用maven创建普通项目命令行程序详解

    大部分使用maven创建的是web项目,这里使用maven创建一个命令行程序,目的是让大家了解maven特点和使用方式,有需要的朋友可以借鉴参考下
    2021-10-10
  • SpringMVC @RequestMapping注解属性详细介绍

    SpringMVC @RequestMapping注解属性详细介绍

    通过@RequestMapping注解可以定义不同的处理器映射规则,下面这篇文章主要给大家介绍了关于SpringMVC中@RequestMapping注解用法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • MyBatis如何使用(三)

    MyBatis如何使用(三)

    这篇文章主要介绍了MyBatis如何使用(三)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • Sentinel Dashboard限流规则保存方式

    Sentinel Dashboard限流规则保存方式

    这篇文章主要介绍了Sentinel Dashboard限流规则保存方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 浅析Java中静态代理和动态代理的应用与区别

    浅析Java中静态代理和动态代理的应用与区别

    代理模式在我们生活中很常见,而Java中常用的两个的代理模式就是动态代理与静态代理,这篇文章主要为大家介绍了二者的应用与区别,需要的可以参考下
    2023-08-08
  • Java局部变量线程安全原理分析

    Java局部变量线程安全原理分析

    这篇文章主要介绍了Java局部变量线程安全原理分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Spring基于注解配置事务的属性

    Spring基于注解配置事务的属性

    这篇文章主要为大家详细介绍了Spring基于注解配置事务的属性,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • plantuml画图实现代码画时序图UML用例图

    plantuml画图实现代码画时序图UML用例图

    这篇文章主要为大家介绍了plantuml画图实现代码画时序图示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Spring Boot之Validation自定义实现方式的总结

    Spring Boot之Validation自定义实现方式的总结

    这篇文章主要介绍了Spring Boot之Validation自定义实现方式的总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论