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

网友投稿 308 2022-10-13


解决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.sprhttp://ingframework.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 void beanCopy(T source, T target) {

BeanUtils.copyProperties(source, target, getNullPropertyNames(source));

}

//source中的非空属性复制到target中,但是忽略指定的属性,也就是说有些属性是不可修改的(个人业务需要)

public static 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 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 emptyNames = getNullPropertyNameSet(source);

String[] result = new String[emptyNames.size()];

return emptyNames.toArray(result);

}

public static Set getNullPropertyNameSet(Object source) {

final BeanWrapper src = new BeanWrapperImpl(source);

java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:“光进铜退” | 拥抱光,建设“城市光网”
下一篇:全光医院 | 一网万联全光纤网络解决方案,助力医疗行业数字化转型!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~