有不同的方法(很多)
方法 1 - 使用 @Id 更新代码
这类似于@kriegaex 的建议,在您的代码中添加@Id 注释并如下更新类
public class ListItem {
@Id
private String itemName;
private String itemValue;
}
方法 2 - 实体注册
Method 1 有一个缺点,它需要对您的实际模型进行代码更改,并且可能并不总是可行或可取的。在这种情况下,您需要手动注册您的实体
public static void main(String[] args) {
List<ListItem> list1 = ImmutableList.of(
ListItem.builder()
.itemName("item1")
.itemValue("value")
.build(),
ListItem.builder()
.itemName("item2")
.itemValue("value2")
.build()
);
List<ListItem> list2 = ImmutableList.of(
ListItem.builder()
.itemName("item2")
.itemValue("value2change")
.build(),
ListItem.builder()
.itemName("item1")
.itemValue("value")
.build(),
ListItem.builder()
.itemName("item3")
.itemValue("value3")
.build()
);
TopLevelClass tlc1 = TopLevelClass.builder().items(list1).build();
TopLevelClass tlc2 = TopLevelClass.builder().items(list2).build();
Javers jvc = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET)
.registerEntity(new EntityDefinition(ListItem.class, "itemName"))
.build();
Diff diffTlc = jvc.compare(tlc1, tlc2);
System.out.println(diffTlc);
}
上面运行的输出如下
* changes on com.javerstest.ListItem/item2 :
- 'itemValue' changed from 'value2' to 'value2change'
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.ListItem@306a04bf' removed
. 'com.javerstest.ListItem@306a04fb' added
. 'com.javerstest.ListItem@29f62baf' added
* new object: com.javerstest.ListItem/item3
没有.registerEntity(new EntityDefinition(ListItem.class, "itemName")),它是
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.ListItem@306a04bf' removed
. 'com.javerstest.ListItem@306a04fb' added
. 'com.javerstest.ListItem@29f62baf' added
- 'items/0.itemName' changed from 'item1' to 'item2'
- 'items/0.itemValue' changed from 'value' to 'value2change'
- 'items/1.itemName' changed from 'item2' to 'item1'
- 'items/1.itemValue' changed from 'value2' to 'value'
方法 3 - 使用 @IgnoreDeclaredProperties
所以在后面的部分澄清之后,下面是另一种方法
@IgnoreDeclaredProperties
public class ListItem {
private String itemName;
private String itemValue;
}
这将使List 比较未添加的工作和休息项目。但这不会让您直接比较ListItem。
所以推荐的方法是只使用Method 2,如果你不想对你的模型进行代码更改并且完全灵活
方法 4 - 使用@ShallowReference
可以将@ShallowReference 添加到项目中,然后它会进行适当的集合比较
public class TopLevelClass {
@ShallowReference
List<ListItem> items;
}
目前截至 18 年 5 月 2 日,由于稍后解释的错误,这不起作用
方法 5 - 使用集合
如果需要,您可以在课堂上使用 Set 代替 List
public class TopLevelClass {
Set<ListItem> items;
}
并且更新后的比较代码将是
TopLevelClass tlc1 = TopLevelClass.builder().items(new HashSet<ListItem>(list1)).build();
TopLevelClass tlc2 = TopLevelClass.builder().items(new HashSet<ListItem>(list2)).build();
Javers jvc = JaversBuilder.javers().build();
输出如下
Diff:
* new object: com.javerstest.TopLevelClass/#items/bd3fdf9ee4c8eb797ca392a1f8eb28c6
* new object: com.javerstest.TopLevelClass/#items/ad5b96d68b6742a92d330f0d98bae8b3
* object removed: com.javerstest.TopLevelClass/#items/a1961e7fd2e23b166e4d1b2acbe67263
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.TopLevelClass/#items/a1961e7fd2e23b166e4d1b2acbe67263' removed
. 'com.javerstest.TopLevelClass/#items/bd3fdf9ee4c8eb797ca392a1f8eb28c6' added
. 'com.javerstest.TopLevelClass/#items/ad5b96d68b6742a92d330f0d98bae8b3' added
方法 6 - 将 ListItem 注册为值
在这里你可以注册ListItem作为一个值
Javers jvc = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET)
.registerValue(ListItem.class)
.build();
Diff diffTlc = jvc.compare(tlc1, tlc2);
System.out.println(diffTlc);
输出是
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.ListItem@306a04bf' removed
. 'com.javerstest.ListItem@306a04fb' added
. 'com.javerstest.ListItem@29f62baf' added
功能?/ BUG? /限制?
如果您在没有.registerEntity(new EntityDefinition(ListItem.class, "itemName")) 的情况下查看我们的Method2 的输出,现在代码中发生的另一件事如下所示
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.ListItem@306a04bf' removed
. 'com.javerstest.ListItem@306a04fb' added
. 'com.javerstest.ListItem@29f62baf' added
这基本上是因为ListCompareAlgorithm.AS_SET,如果你把它改成SIMPLE,输出会变成下面
- 'items' collection changes :
0. '...ListItem/item1' changed to '...ListItem/item2'
1. '...ListItem/item2' changed to '...ListItem/item1'
2. '...ListItem/item3' added
所以在我们的原始代码中
Javers jvc = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET).build();
Diff diffTlc = jvc.compare(tlc1, tlc2);
首先,它仅使用set 比较list,并添加如下更改
* changes on com.javerstest.TopLevelClass/ :
- 'items' collection changes :
. 'com.javerstest.ListItem@306a04bf' removed
. 'com.javerstest.ListItem@306a04fb' added
. 'com.javerstest.ListItem@29f62baf' added
但随后它又走得更远,并且对数组的每个项目也进行了另一个差异,这就是添加额外差异的原因
- 'items/0.itemName' changed from 'item1' to 'item2'
- 'items/0.itemValue' changed from 'value' to 'value2change'
- 'items/1.itemName' changed from 'item2' to 'item1'
- 'items/1.itemValue' changed from 'value2' to 'value'
所以并不是没有选择AS_SET,而是首先对list 和set 以及在单个项目级别进行差异。我提出了一个相同的问题以便更好地理解它
https://github.com/javers/javers/issues/669