Javers – comparison String, Collection and Boolean with defined rules

Tags: , , , ,

I have 2 classes:

public class Boss {
    private String name;
    private List<Employee> subordinates;

public class Employee {
    private String name;
    private Boolean hasDrivingLicense;
    private List<Employee> colleagues;

And also my own defined comparators(rules):

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();

These comparators are defined so that an empty String is treated the same as null, an empty Collection is treated the same as null, and a Boolean false is treated the same as null. In the main method I try to compare 2 objects so as to check if the defined comparators work.

public static void main(String[] args) {

        Employee employee1 = Employee.builder()
                .colleagues(new ArrayList<>())

        Employee employee2 = Employee.builder()

        Boss boss1 = Boss.builder()

        Boss boss2 = Boss.builder()

        final Javers javers = JaversBuilder.javers()
        final Diff diff = javers.compare(boss1, boss2);

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

Unfortunately, the comparison does not work as expected. In JaversBuilder I tried add .registerValue(String.class, (a, b) -> StringUtils.equals(a,b)) but it also dont work. Result of print:

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

What should I change to make it work. If comparators were working correctly In this example, diff would not have any changes


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

Source: stackoverflow