将 CustomPropertyComparator 与 java.util.List 一起使用

Using CustomPropertyComparator with java.util.List

我创建了一个 CustomPropertyComparator 用于比较由 JAXB 创建的对象。因此,就我而言,我无法使用框架提供的 @DiffIgnore 注释。此外,JAXB 生成的集合基于 java.util.List 而不是 java.util.Collection。不幸的是,我无法让 javers 使用我的 CustomPropertyComparatorList 界面。

public class Person {    
    private String name;
    private String ignoreThis;
}

public class Company {
    private String id;
    private Person owner;
    private Collection<Person> clients;
    private List<Person> partners;
}

Comparator只比较名字,忽略ignoreThis字段:

public class EntityComparator implements CustomPropertyComparator<Person, ValueChange> {
    public ValueChange compare(Person left, Person right, GlobalId affectedId, Property property) {
        if (left.getName().equals(right.getName()))
            return null;
        return new ValueChange(affectedId, "entity/name", left.getName(), right.getName());
    }    
}

我的测试用例是这样的:

这个测试有效,因为它比较集合

@Test
public void equalEntityClientTest() {
    Person e1 = new Person("james", "ignore this");
    Company le1 = new Company("1", null, Arrays.asList(e1), null);

    Person e2 = new Person("james", "");
    Company le2 = new Company("1", null, Arrays.asList(e2), null);
    Diff diff = javers.compare(le1, le2);

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

这个测试失败了,因为它没有使用我的比较器来比较实体并且忽略字段的差异是 true

@Test
public void equalEntityPartnerTest() {
    Person e1 = new Person("james", "ignore this");
    Company le1 = new Company("1", e1, null, Arrays.asList(e1));

    Person e2 = new Person("james", "");
    Company le2 = new Company("1", e2, null, Arrays.asList(e2));
    Diff diff = javers.compare(le1, le2);

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

在 javers 的参考中,他们解释说如果你有一个自定义的集合接口,你需要实现你自己的比较器,如果你使用一个不基于 java.util.Collection 的集合,这是可以的。但实际上,我希望 javers 库支持 java.util.List。 此外,我无法弄清楚如何 add/create 列表接口的比较器。

可在 https://github.com/baumgartner/javerstest

下找到工作示例

你在这里触及了两个问题。 您的第一个测试通过了,因为 Javers 忽略了 Collection 属性并且只记录了这个警告:

10:19:40.332 [main] WARN  o.j.c.d.a.CollectionChangeFakeAppender - Collections: Field Collection<Person> clients; //declared in Company
are not equals but can't be compared. Raw Collection properties are not supported. Expected Set, List or any of their subclasses. JaVers uses different algorithms for comparing Sets and Lists and needs to know (statically) which one to test.

我觉得不行,所以我创建了一个问题,见https://github.com/javers/javers/issues/746

第二期涉及CustomPropertyComparator。它旨在比较像 Multimap 这样的大型结构,并且在比较 List 项时 JaVers 不会调用它,因为当您比较 List 项时您需要 boolean equals(a,b) 方法。这就是 CustomValueComparator 所做的。

尽管如此,CustomPropertyComparator 也可以扩展为具有 boolean equals(a,b) 方法。我为此创建了第二期,请参阅 https://github.com/javers/javers/issues/747