You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Javers的Diff结果创建仅含变更字段的实体对象?

用Javers生成仅含变更字段的实体对象

刚接触Javers的话,确实会想有没有现成的快捷方式来生成这种只保留变更字段的实体——可惜Javers本身并没有直接提供这个功能,但我们可以利用它返回的Diff对象里的变更信息,结合反射或者Bean工具类来轻松实现,步骤其实很简单:

步骤1:调整实体类适配null值

首先你的Person类如果要支持字段为null,建议把基本类型换成包装类(比如int改成Integer),同时加上无参构造器方便创建空实例:

@AllArgsConstructor
@NoArgsConstructor
class Person {
    @Id 
    String name;
    Integer age;
    String address;
}

步骤2:获取Diff对象并提取变更记录

先通过Javers.compare()拿到两个对象的差异,然后从Diff里筛选出所有属性变更:

Person person1 = new Person("Bob", 20, "Brooklyn");
Person person2 = new Person("Bob", 25, "Queens");

Javers javers = JaversBuilder.javers().build();
Diff diff = javers.compare(person1, person2);

// 获取所有属性变更的记录
List<PropertyChange> propertyChanges = diff.getChangesByType(PropertyChange.class);

步骤3:构建仅含变更字段的实体

创建一个空的Person实例,然后遍历变更记录,只把发生变更的字段设置为新值(来自person2),其他字段保持null:

// 创建空实例,所有字段初始为null
Person changedOnlyPerson = new Person();

// 遍历变更,给对应字段赋值
for (PropertyChange change : propertyChanges) {
    String fieldName = change.getPropertyName();
    Object newValue = change.getRightValue(); // 变更后的新值
    
    // 用Spring的BeanUtils简化属性设置(没有Spring的话也可以自己写反射逻辑)
    try {
        org.springframework.beans.BeanUtils.setProperty(changedOnlyPerson, fieldName, newValue);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这样生成的changedOnlyPerson就只有age(25)和address(Queens)有值,name保持null——完全符合你“仅保留变更字段,其余为null”的需求。

小补充

  • 如果实体的ID字段也可能发生变更(虽然业务上一般不建议),这个逻辑也能自动处理,因为ID字段的变更也会被Javers捕获到。
  • 要是不想依赖Spring的工具类,用JDK原生反射也能实现字段赋值,只是代码会稍微繁琐一点,核心逻辑都是遍历变更记录然后设置对应字段。

内容的提问来源于stack exchange,提问作者knk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:22:20