2

Can Javers compare two sets to identify the changes happened in the objects in the new set for each corresponding object in the old set?

Does the implementation rely on the equals method of the value object class? I implemented equals method for my value object, but it still seems to treat them as different objects. If it is not using the equals method, can we do that? Because, Java Set itself relies on the equals method to make sure no duplicates exist in the set.

Please suggest.

In the below test case, I'm using sysCode and localId as a combined identifier for the object, not including the goldenId. But the diff (output below the class) is not recognizing that equal objects and showing the diff as all the objects in the old set as removed and the objects in the new se as added, which doesn't seem to add any value.

Here is my test case:

Javers javers = JaversBuilder.javers().build();
SetConMap oldMap = new SetConMap();
Set<Contact> oldSysCons = new HashSet<>();
oldMap.setSysCons(oldSysCons);
oldSysCons.add(new Contact().sysCode("AL").localId("123").goldenId("ABC"));
oldSysCons.add(new Contact().sysCode("AL").localId("456").goldenId("ABC"));

SetConMap newMap = new SetConMap();
Set<Contact> newSysCons = new HashSet<>();
newMap.setSysCons(newSysCons);
newSysCons.add(new Contact().sysCode("AL").localId("123").goldenId("DEF"));
newSysCons.add(new Contact().sysCode("AL").localId("456").goldenId("DEF"));
newSysCons.add(new Contact().sysCode("AL").localId("789").goldenId("DEF"));

Diff diff = javers.compare(oldMap, newMap);
System.out.println(diff);
private static class Contact {
    private String sysCode;
    private String localId;
    private String goldenId;
//getters, setters.
    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && (obj instanceof Contact) && Objects.equals(sysCode, ((Contact) obj).getSysCode())
            && Objects.equals(localId, ((Contact) obj).getLocalId());
    }
}

Diff:

* new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/c76fadcd55d4dbf6d8cbe49310b1ab26
* new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/96b23b34a0f42a5105491350db5c46f1
* new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a9c7f46bbe5f0e46b5751f3f5c5d8542
* object removed: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a53e4ba1b22c4f290a80daf40adf5d81
* object removed: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/782edf187b8add9bab004ca06f7b6c7c
* changes on org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/ :
  - 'sysCons' collection changes :
    . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/782edf187b8add9bab004ca06f7b6c7c' removed
    . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a53e4ba1b22c4f290a80daf40adf5d81' removed
    . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a9c7f46bbe5f0e46b5751f3f5c5d8542' added
    . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/c76fadcd55d4dbf6d8cbe49310b1ab26' added
    . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/96b23b34a0f42a5105491350db5c46f1' added
barbsan
  • 3,418
  • 11
  • 21
  • 28
ndsurendra
  • 413
  • 1
  • 5
  • 15

1 Answers1

0

The Contact class is considered as a Value Object by Javers: in this case, it performs a property by property comparison (see here).

To get more detailed comparison results, you may transform the Contact class into an Entity using the @Id annotation on one of its properties.

Another solution may be to write a custom comparator here (but I never tried it).

Fouad HAMDI
  • 456
  • 2
  • 4
  • But, with this, we won't be able to detect any changes that happened to the Contact object, say the GoldenId in this case, because we are adding @DiffIgnore to all the properties except the object identifiers. – ndsurendra Jun 20 '19 at 08:44
  • My understanding was that the goldenId changes were not interesting since it is not used in the equals() method. If you are interested in goldenId changes, why the default behavior of Javers wouldn't fit your use case (property by property comparison) ? Can you describe the output that you expect from your sample code to get a clearer idea ? – Fouad HAMDI Jun 21 '19 at 11:54
  • I'm expecting the output something like this: changes: contact with syscode: AL, localId; 123:: changed goldenId from ABC to DEF,,, contact with syscode: AL, localId; 456:: changed goldenId from ABC to DEF,,, added contact with syscode: AL, localId: 789 with goldenId: DEF – ndsurendra Jun 22 '19 at 11:56
  • oh, I understand the needs. This kind of comparison will not work with Value Objects but with Entities. If you add an @Id annotation on the localId property of your Contact class, you may obtain what you expect (supposing that it makes sense to use that field as an identity property) – Fouad HAMDI Jun 24 '19 at 15:46