I've created a CustomPropertyComparator
to use it to compare Objects which were created by JAXB. So, in my case, I am not able to use the @DiffIgnore
annotation offered by the framework. Also, the Collections generated by JAXB are based on java.util.List
and not java.util.Collection
. Unfortunately, I couldn't manage to make javers use my CustomPropertyComparator
with the List
Interface.
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
that only compares the name, but ignores the ignoreThis
field:
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());
}
}
My test-cases looks like this:
This tests works, cause it compares the collection
@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());
}
This test fails, cause it doesn't use my comparator to compare the entity and the diff of the ignored field is 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());
}
In the reference of javers, they explain if you have a custom Collection-Interface you need to implement your own comparator, which is okay if you use a collection not based on java.util.Collection
. But actually, I would expect that java.util.List
is supported by the javers Library.
Also I wasn't able to figure out how I can add/create a Comparator for the List-Interface.
A working example can be found under https://github.com/baumgartner/javerstest
You have touched two issues here.
Your first test passes because Javers ignores Collection
properties and only this warning is logged:
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.
I think it's not OK, so I have created an issue, see https://github.com/javers/javers/issues/746
Second issue concerns CustomPropertyComparator
. It was designed to compare large structures like Multimap, and it's not called by JaVers when comparing List items, because when you are comparing List items you need boolean equals(a,b)
method. That's what CustomValueComparator
does.
Although, CustomPropertyComparator can be extended to have also boolean equals(a,b)
method. I have created the second issue for that, see https://github.com/javers/javers/issues/747