Javers复杂对象图比较咨询:是否需用自定义属性比较器?
Javers 处理复杂层级+List集合对象对比的实操建议
首先给结论:绝大多数场景下不需要自定义CustomPropertyComparator,先把Javers原生的配置用透再说。
1. 原生支持搞定层级与集合对比
Javers本身就设计用来处理复杂对象图,你的Step→Procedure→Solution层级结构,只要给对应的类做好基础注解:
- 给需要追踪实体身份的类加
@Entity+@Id - 纯值对象(没有唯一ID,靠内容判断相等)加
@ValueObject
Javers会自动递归遍历所有嵌套属性,对比每个层级的字段变化。
对于List集合:
- 默认是有序对比:会追踪元素的增删、位置移动,以及元素内容的变化
- 如果想忽略顺序,只对比元素存在性/内容,给List字段加
@CollectionType(type = CollectionType.SET),Javers会把它当作无序集合处理 - 如果元素是实体,Javers会按ID判断相等;如果是值对象,会按所有字段内容判断相等——这些都是原生支持的,不用额外写代码
2. 什么时候才需要CustomPropertyComparator?
只有当Javers原生逻辑完全不符合你的业务规则时才需要自定义,比如:
- 某个List的元素对比需要忽略特定字段(比如只对比Step的
id和name,忽略createTime) - 集合元素是自定义的特殊类型(比如自定义枚举、第三方库类型,Javers无法自动识别相等性)
- 需要自定义集合变化的追踪逻辑(比如把某些元素的修改判定为新增)
3. 要不要为不同List写多个自定义比较器?
没必要。你有两种更高效的方式:
方式一:按字段精准绑定
给需要特殊处理的List字段单独指定比较器,其他List用原生逻辑:
public class Procedure { // 这个List用自定义比较器 @JaversProperty(comparator = StepListCustomComparator.class) private List<Step> coreSteps; // 这个List用原生逻辑 private List<Step> auxiliarySteps; }
方式二:在一个比较器内处理多类型
如果多个List的自定义逻辑有共性,可以在同一个比较器里通过判断元素类型或字段名来分支处理:
public class MultiTypeListComparator implements CustomPropertyComparator<List<?>, ValueChange> { @Override public ValueChange compare(List<?> left, List<?> right, Property property, Javers javers) { if (property.getName().equals("coreSteps")) { // 处理Step类型的List自定义逻辑 } else if (property.getName().equals("solutionList")) { // 处理Solution类型的List自定义逻辑 } // 返回null则沿用Javers原生对比逻辑 return null; } }
然后注册这个比较器即可,不用写多个。
最后建议
先拿原生配置跑通你的对象对比需求,遇到具体的不符合预期的对比结果时,再针对性地调整注解或写自定义比较器——不要一开始就想着自定义,反而会增加复杂度。
内容的提问来源于stack exchange,提问作者barun
相关产品推荐
相关产品推荐

