首页 > 解决方案 > Javers - 将字符串、集合和布尔值与定义的规则进行比较

问题描述

我有 2 节课:

@Data
@Builder
public class Boss {
    
    private String name;
    
    private List<Employee> subordinates;
}

@Data
@Builder
public class Employee {
    
    private String name;
    
    private Boolean hasDrivingLicense;
    
    private List<Employee> colleagues;
}

还有我自己定义的比较器(规则):

public class StringComparator implements CustomValueComparator<String> {

    public boolean equals(String s, String t1) {
        return (s != null && s.equals("") && t1 == null) || (s == null && t1 !=  null && t1.equals(""));
    }

    public String toString(String s) {
        return s;
    }
}

public class CollectionComparator<T> implements CustomValueComparator<Collection<T>> {
    
    public boolean equals(Collection<T> ts, Collection<T> t1) {
        return (ts == null && t1 != null && t1.isEmpty()) || (ts != null && ts.isEmpty() && t1 == null);
    }

    public String toString(Collection<T> ts) {
        return ts.toString();
    }
}

public class  BooleanComparator implements CustomValueComparator<Boolean> {

    public boolean equals(Boolean aBoolean, Boolean t1) {
        return (aBoolean == null && t1 != null && t1.equals(false)) 
                || (aBoolean != null && aBoolean.equals(false) && t1 == null);
    }

    public String toString(Boolean aBoolean) {
        return aBoolean.toString();
    }
}

这些比较器被定义为将空字符串视为与 null 相同,将空集合视为与 null 相同,并将布尔 false 视为与 null 相同。在主要方法中,我尝试比较 2 个对象,以检查定义的比较器是否有效。

public static void main(String[] args) {

        Employee employee1 = Employee.builder()
                .name("Krzysztof")
                .colleagues(new ArrayList<>())
                .hasDrivingLicense(false)
                .build();

        Employee employee2 = Employee.builder()
                .name("Krzysztof")
                .colleagues(null)
                .hasDrivingLicense(null)
                .build();

        Boss boss1 = Boss.builder()
                .name("")
                .subordinates(Arrays.asList(employee1))
                .build();

        Boss boss2 = Boss.builder()
                .name(null)
                .subordinates(Arrays.asList(employee2))
                .build();

        final Javers javers = JaversBuilder.javers()
                .registerValue(CollectionComparator.class)
                .registerValue(StringComparator.class)
                .registerValue(BooleanComparator.class)
                .build();
        final Diff diff = javers.compare(boss1, boss2);

        System.out.println(diff.getChanges().size() == 0);
        System.out.println(diff.getChanges().size());
        System.out.println(diff);
    }

不幸的是,比较没有按预期进行。在 JaversBuilder 我尝试添加 .registerValue(String.class, (a, b) -> StringUtils.equals(a,b)) 但它也不起作用。打印结果:

false
2
Diff:
* changes on Boss/ :
  - 'name' value changed from '' to ''
  - 'subordinates/0.hasDrivingLicense' value changed from 'false' to ''

我应该改变什么才能让它工作。如果比较器工作正常在这个例子中,diff 不会有任何变化

标签: javastringcollectionsbooleanjavers

解决方案


I think this problem is caused by your assumption that CustomValueComparators can provide some custom logic for nulls. This assumption is sensible but false. Currently, CustomValueComparators always get non-null values to compare. Javers itself deals with nuls.

I have created an issue to manage this https://github.com/javers/javers/issues/1075


推荐阅读