-3

Firstlty, Just Check four models Owners, Owner, Addresss(Its different from yours), CodeInfo from here https://github.com/rckr20/javers/tree/master/javerscore/src/test/java/org/javers/core/examples/model

Now what i am doing is comparing two Owners object using LEVENSHTEIN_DISTANCE algorithm in this way.

/*Comparing List */
Owners Owners1 = new Owners();
Owners1.add(new Owner(1,new Addresss("Delhi",null,new CodeInfo(null))));

Owners Owners2 = new Owners();
Owners2.add(new Owner(2,new Addresss("Noida","SEZ",new CodeInfo("abc"))));

Diff diff = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE).build().compare(Owners1, Owners2);

Now you will ask why i am not using simply List instead of using Owners(which is extending ArrayList of Owner). Secondly I can't use compareCollection() here. My current project architecture is like that and i can't change that.

So on comparison what i need is value changes but its returning the list change.

Diff:

changes on org.javers.core.graph.LiveGraphFactory$ListWrapper/ :
'list' collection changes :
0. 'org.divik.javers.JaversBasic.Owner@3f0846c6' changed to 'org.divik.javers.JaversBasic.Owner@77a98a6a'
And just for solving this i just tried to convert the Owners object into the JsonNode.

You can also check this https://easyupload.io/aez105

Just tried by mapping owner as Entity but the same noisy results. But got the solution We can compare it like this.

Diff diff = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE).build().compareCollections(((List)Owners1), (List)Owners2,Owner.class);

But facing problem again if I have Owners(i.e class extending array list) nested inside some model

   Example:--
    class Car{
  @Id
   int id;
   Owners owners;

   public Car(int id, Owners owners) {
     this.id= id;
     this.owners = owners;
    }
   }

Again I am getting noisy results.

2 Answers2

0

Your problem is your idea of using Owners.class

class Owners extends ArrayList<Owner> implements Serializable {        
}

which extends ArrayList and adds nothing. In this case, javers doesn't recognize the type parameter and treats Owners as List<Object> which results in simplified diff.

When you are comparing top-level collections, you should use the right method for comparing collections which is named compareCollections and which is well described in javers' API:

    /**
     * Deeply compares two top-level collections.
     * <br/><br/>
     *
     * Introduced due to the lack of possibility to statically
     * determine type of collection items when two top-level collections are passed as references to
     * {@link #compare(Object, Object)}.
     * <br/><br/>
     *
     * @see <a href="http://javers.org/documentation/diff-examples/#compare-collections">
     *     Compare top-level collections example</a>
     */
    <T> Diff compareCollections(Collection<T> oldVersion, Collection<T> currentVersion, Class<T> itemClass);

usage:

Diff diff = javers.compareCollections(Owners1, Owners2, Owner.class)
Bartek Walacik
  • 3,386
  • 1
  • 9
  • 14
  • 1. Anything which I can do to make javers understand the type of Owners. 2. As there are multiple list in my actual use case and It will not be efficient to compare each one using compareCollection as they are not at top level. 3. Can i implement something like CustomList or Property comparator and register it for every such list with the itemType.class EXAMPLE:-- javers = JaversBuilder.javers() .registerCustomType(Owners, new CustomListComparator()) And override CustomListComparator method and call compareCollection and pass the type i.e Owner in this case inside it – Divik Arora Dec 10 '19 at 16:06
0
  1. Anything which I can do to make javers understand the type of Owners.

  2. As there are multiple list in my actual use case and It will not be efficient to compare each one using compareCollection as they are not at top level.

  3. Can i implement something like CustomList or Property comparator and register it for every such list with the itemType.class

EXAMPLE:-- javers = JaversBuilder.javers() .registerCustomType(Owners, new CustomListComparator())

And override CustomListComparator method and call compareCollection and pass the type i.e Owner in this case inside it.