javers:识别或避免重复的差异结果

时间:2017-02-13 14:20:35

标签: javers

我正在使用JaVers v3.0.0比较包含对象列表的两个对象。我正在比较的对象在列表的内容上有所不同,例如,从列表中删除了一个对象。

执行此比较时,我得到两个更改对象:一个ListChange和一个ObjectRemoved。

在展示结果时,我需要确保相同的更改不会出现两次。我很难弄清楚如何识别或避免我得到的这些重复。我已经尝试过使用GlobalID,但我最终解析了感觉不完全安全的字符串。我也尝试从我的演示文稿中跳过ListChange或ObjectRemoved,但是当我还有一个值列表的ListChange或者一个不在列表中的对象的ObjectRemoved时,这会出现问题。

@Test
public void javersDuplicateDiffResult() {

    MyMainObj objA = new MyMainObj(Arrays.asList(new MyListedObj("hello"), new MyListedObj("world")));
    MyMainObj objB = new MyMainObj(Arrays.asList(new MyListedObj("hello")));

    Javers javers = JaversBuilder.javers()
            .withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE)
            .build();
    Diff res = javers.compare(objA, objB);

    System.out.println(res);

    Assert.assertEquals(1, res.getChanges().size());
}

class MyMainObj {
    private List<MyListedObj> theObjectList;

    public MyMainObj(List<MyListedObj> anObjectList) {
        this.theObjectList = anObjectList;
    }
}

class MyListedObj {
    private String theText;

    public MyListedObj(String aText) {
        this.theText = aText;
    }
}

以下是运行上面示例代码的输出:

Diff:
1. ObjectRemoved{globalId:'org.example.TestJavers$MyMainObj/#theObjectList/1'}
2. ListChange{globalId:'org.example.TestJavers$MyMainObj/', property:'theObjectList', containerChanges:[(1).removed:'org.example.TestJavers$MyListedObj@2aece37d']}


java.lang.AssertionError: 
Expected :1
Actual   :2

2 个答案:

答案 0 :(得分:0)

在JaVers中,ObjectRemoved通知您对象从左侧的对象图中消失。虽然ListChange->ValueRemovedPropertyChange,但会告知对象图中发生更改的具体位置。

这两个更改涉及同一个对象(已删除一个),但不是重复。

例如:

Class A {
  List<B> listOfB
  B bRef
}

如果你比较:

def b1 = new B()
javers.compare( new A(listOfB:[b1], bRef:b1), new A(listOfB:[], bRef:null) )

您将进行三项更改:

  • b1 ObjectRemoved(一般信息)
  • b1 ListChange->ValueRemoved位于listOfB属性(对象图中的特定位置)
  • ValueChanged从b1到{{​​1}}属性上的null(对象图中的另一个特定位置)

我建议您完全忽略bRef更改,仅依赖于ObjectRemovedPropertyChangesListChange ...)

答案 1 :(得分:0)

据我所知,Javers无法实现这一目标。我通过基于更改的路径过滤出重复的差异来解决了类似的问题。

  1. 标识更改的路径(列表更改或值更改) 您将必须编写代码以生成路径

  2. 如果路径是Array ( [0] => stdClass Object ( [download] => 8.63058 [upload]=>2.95235 [date] => 2019 03 23 12:16 ) [1] => stdClass Object ( [download] => 10.94184 [upload]=>2.87722 [date] => 2019 03 23 12:17 ) [2] => stdClass Object ( [download] => 11.37850 [upload]=>3.58455 [date] => 2019 03 23 12:18 ) ) Object Removed的子路径,请忽略它

就您而言,
差异1:ObjectRemoved路径:theObjectList / 1
Diff2:ValueRemoved路径:theObjectList / 1 / MyListedObj @ 2aece37d

您可以丢弃Diff2,因为该路径是已删除对象的子路径。

通过将ListChange路径与Value Change路径串联来构建ValueRemoved路径