2

Using Javers 3.0.2, I need to compare collections of complex objects being nested fields in a object, sometimes it can be even list of elements inside of another list of elements and so on. I'm using Levenshtein list comparision, and it requires object of the list to have field defined as Id. I'm ok to define Id field for required objects, but problem of such approach is that I cannot understand full path of changed object in hierarchy graph. So ideally I would like to have the same behavior as for Entities, but to have Id generated the same way as for ValueObjects.

So, case that I'm trying to describe is following

class A {
    @Id
    private String field0;
    private List<B> bList;
}
class B {
    @Id
    private String field1;
    private String field2;
    private List<C> cList;
}
class C {
    @Id
    private String field3;
    private String field4;
}

And I need to compare 2 objects of class A. I understand that to have adequate comparision of collections using Levensteing algorithm I need to hava @Id annotation on B and C classes. However in this case I received changes for example like C@field3#field4 but I cannot say to which B object changed C object belongs, so I cannot effectively build hierarchy of changed objects like A->bList[1]->cList[2]

In case of ValueObjects I have full path of changes, but It's not possible to use ValueObjects as elements of collections.

Hulk
  • 6,399
  • 1
  • 30
  • 52
Denis
  • 31
  • 4

2 Answers2

1

You can extract a path from ValueObjectId.getFragment()

class A {
    @Id
    private String id;
    private List<B> bList;
}
class B {
    private String field1;
    private String field2;
    private List<C> cList;
}
class C {
    private String field3;
    private String field4;
}

def "should  "(){
  given:
  def a = new A(id:1, bList: [new B(cList: [new C(field3: 'a')])])
  def b = new A(id:1, bList: [new B(cList: [new C(field3: 'b')])])

  when:
  def javers = JaversBuilder.javers().build()
  def diff = javers.compare(a, b)
  println diff.prettyPrint()

  then:
  true
}

output:

Diff:
1. ValueChange{globalId:'org.javers.core.cases.StackCase$A/1#bList/0/cList/0', property:'field3', oldVal:'a', newVal:'b'}
Bartek Walacik
  • 3,386
  • 1
  • 9
  • 14
  • 1
    Yes, I tried this approach initially. However, collection comparison in this case generates too many Change objects, it cannot effectively compare elements of collection if their indexes was changed. So that's why I started trying usage of Id and entities, and so I came with this question – Denis Mar 16 '17 at 18:40
0

You should map A also as Entity. Give it an Id.

Bartek Walacik
  • 3,386
  • 1
  • 9
  • 14
  • So, I've changed this example, but actually result is the same - if user changes cList field (for example), in such approach I cannot find path from cList object -> B -> A – Denis Mar 14 '17 at 22:12