JaVers дает неверный результат для пользовательского списка различий - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть класс Node и список устройств. Например,

    class Node {
        String nodeCode;
        String name;
        List devices;
    }

    class Device {
        String deviceCode;
        String name;
    }

Я сравниваю два объекта Node с использованием алгоритма LEVENSHTEIN_DISTANCE и сценария ios, упомянутых ниже:

Senario - 1. Удалить устройство 1:

 Old Version:
         var device1 = Device("d1", "device1")
         var device2 = Device("d2", "device2")
         var devices = mutableListOf<Device>()
         devices.add(device1)
         devices.add(device2)
         val before = Node("n1", "node1", devices)  // Old Version


 Current Version:
       var newDevice1 = Device("d1", "device1")
       var newDevices = mutableListOf<Device>()
       newDevices.add(newDevice1)
       var after = Node("n1", "node1", newDevices) // New Version

 Compare both version:
 var diff = javers.compare(before, after)
 println("$diff")

Output:

changes on com.example.audit.Node/ :
'devices' collection changes :
1. 'com.example.audit.Node/#devices/1' removed

Senario - 2. Добавить устройство2:

  Old Version:
       var newDevice1 = Device("d1", "device1")
       var newDevices = mutableListOf<Device>()
       newDevices.add(newDevice1)
       var after = Node("n1", "node1", newDevices) // Old Version

  Current Version:
       var device1 = Device("d1", "device1") 
       var device2 = Device("d2", "device2")
       var devices = mutableListOf<Device>()
       devices.add(device1)
       devices.add(device2)
       val after1 = Node("n1", "node1", devices)  // New Version

  Compare both version:
  var diff = javers.compare(after, after1)

Output:

changes on com.example.audit.Node/ :
'devices' collection changes :
1. 'com.example.audit.Node/#devices/1' added

Senario - 3. Удалить устройство 1 из позиции 0 в списке устройств:

  Old Version:
       var device1 = Device("d1", "device1") 
       var device2 = Device("d2", "device2")
       var devices = mutableListOf<Device>()
       devices.add(device1)
       devices.add(device2)
       val after1 = Node("n1", "node1", devices)  //Old Version

 Current Version:
      device2 = Device("d2", "device2") 
      var newDevices2 = mutableListOf<Device>()
      newDevices2.add(device2)
      val after2 = Node("n1", "node1", newDevices2) // New Version

    Compare both version:
    diff = javers.compare(after1, after2)

Output:

changes on com.example.audit.Node/ :
'devices' collection changes :
1. 'com.example.audit.Node/#devices/1' removed

3-й сценарий дает неправильный вывод. Я удалил device1 из 0-й позиции в списке, но он дал удаление из 1-й позиции в списке устройств.

Я хочу вывод 3-го сценария, например:

changes on com.example.audit.Node/ :
'devices' collection changes :
0. 'com.example.audit.Node/#devices/0' removed

Имеет ли JaVers ограничения для списка пользовательских объектов?

Я пропустил третий сценарий в моем прототипе. Я пошел и интегрировался в свой проект, и изменения были перенесены на сцену. Это заблокировало меня для освобождения.

Можете ли вы указать, что я должен изменить, чтобы получить ожидаемый результат?

1 Ответ

0 голосов
/ 29 февраля 2020

JaVers работает нормально, вы неправильно используете Value Objects. Списки объектов-значений не удобно сравнивать, поскольку объекты-значения (по определению) не имеют идентичности. Вы можете получить ожидаемый результат, если отобразите ваши объекты в списках как Values

(Groovy)

package org.javers.core.cases

import org.javers.core.JaversBuilder
import org.javers.core.diff.ListCompareAlgorithm
import org.javers.core.diff.changetype.container.ListChange
import org.javers.core.metamodel.annotation.Id
import org.javers.core.metamodel.annotation.TypeName
import spock.lang.Specification

import static java.util.Objects.equals

class shivusajjan extends Specification {

    @TypeName("Address")
    class Address {
        String city
        String street

        Address(String city, String street) {
            this.city = city
            this.street = street
        }

        @Override
        String toString() {
            return "Address{" +
                    "city='" + city + '\'' +
                    ", street='" + street + '\'' +
                    '}';
        }
    }

    @TypeName("Employee")
    class EmployeeClass {
        @Id String name
        List<Address> addressList

        EmployeeClass(String name, List<Address> addressList) {
            this.name = name
            this.addressList = addressList
        }
    }

    def "should compare list of Values using LEVENSHTEIN_DISTANCE"() {
        given:
        def javers = JaversBuilder.javers()
                .withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE)
                .registerValue(
                        Address,
                        { a, b -> equals(a.city, b.city) && equals(a.street, b.street) },
                        {a -> a.toString() }
                )
                .build()

        def previousAddresses = [ new Address("Bangalore", "Vinayaka"),
                                  new Address("Bangalore", "Vijayanagar")]
        def previousEmp = new EmployeeClass("Frodo", previousAddresses)

        def currentAddresses = [ new Address("Bangalore", "Vijayanagar") ]
        def newEmp = new EmployeeClass("Frodo", currentAddresses)

        when:
        def diff = javers.compare(previousEmp, newEmp)

        then:
        println diff.prettyPrint()
        ListChange change = diff.getChangesByType(ListChange)[0]
        change.changes[0].index == 0
    }
}

output

Diff:
* changes on Employee/Frodo :
  - 'addressList' collection changes :
    0. 'Address{city='Bangalore', street='Vinayaka'}' removed
...