比较与 javers 实现相同接口的对象
Comparing objects that implement the same interface with javers
我正在使用 javers (https://javers.org/) 并尝试比较实现相同接口的两个对象。例如,我用苹果和橙子进行了测试。 Apples to Apples 工作正常,但不是 Apples to Oranges。似乎 运行 比较但没有获得新值。
如果我有一个 Fruit super class 和 apples and oranges 扩展它但没有接口运气,这工作正常。
任何熟悉此 API 的人都可以为我指明正确的方向。
型号代码如下:
@TypeName("FruitIface")
@Entity
public interface FruitIface {
public final static String SIZE_SMALL = "Small";
public final static String SIZE_LARGE = "Large";
public final static String CONDITION_RIPE = "Ripe";
public final static String CONDITION_NOT_RIPE = "Not Ripe";
public String getSize();
public String getCondition();
public Double getWeight();
public Date getSellBy();
}
@TypeName("FruitIface")
@Entity
public class Apple implements FruitIface {
private String size;
private String condition;
private Double weight;
private Date sellBy;
@Id
private String compareId;
public Apple (String id,String size, String condition, Double weight, Date sellBy){
this.compareId = id;
this.size = size;
this.condition = condition;
this.weight = weight;
this.sellBy = sellBy;
}
....
}
@TypeName("FruitIface")
@Entity
public class Orange implements FruitIface {
@PropertyName("size")
private String size;
private String condition;
private Double weight;
private Date sellBy;
@Id
private String compareId;
public Orange (String id, String size, String condition, Double weight, Date sellBy){
this.compareId = id;
this.size = size;
this.condition = condition;
this.weight = weight;
this.sellBy = sellBy;
}
....
}
测试用例:
@Test public void testCompareAppleToAppleIface() {
Apple appleOne = new Apple("01",FruitIface.SIZE_LARGE,FruitIface.CONDITION_RIPE, 0.3, new Date());
Apple appleTwo = new Apple("01",FruitIface.SIZE_SMALL,FruitIface.CONDITION_RIPE, 0.2, new Date());
LOGGER.info("\n\nComparing apples to apples...");
Diff diff = javers.compare(appleOne, appleTwo);
LOGGER.info("diff: " + diff);
}
@Test public void testCompareAppleAndOrangeIface() {
Apple apple = new Apple("01",FruitIface.SIZE_LARGE,FruitIface.CONDITION_RIPE, 0.3, new Date()); //(String size, String condition, Double weight, Date sellBy)
Orange orange = new Orange("01",FruitIface.SIZE_SMALL,FruitIface.CONDITION_RIPE, 0.2, new Date());
LOGGER.info("\n\nComparing apples and oranges IFace...");
Diff diff = javers.compare(apple, orange);
LOGGER.info("diff: " + diff);
}
结果:
Comparing apples to apples...
[main] INFO xxx.compare.test.JaversCompareTestIface - diff: Diff:
1. ValueChange{globalId:'FruitIface/01', property:'size', oldVal:'Large', newVal:'Small'}
2. ValueChange{globalId:'FruitIface/01', property:'weight', oldVal:'0.3', newVal:'0.2'}
Comparing apples and oranges IFace...
[main] INFO xxx.compare.test.JaversCompareTestIface - diff: Diff:
1. ValueChange{globalId:'FruitIface/01', property:'size', oldVal:'Large', newVal:''}
2. ValueChange{globalId:'FruitIface/01', property:'condition', oldVal:'Ripe', newVal:''}
3. ValueChange{globalId:'FruitIface/01', property:'weight', oldVal:'0.3', newVal:''}
4. ValueChange{globalId:'FruitIface/01', property:'sellBy', oldVal:'Thu Aug 10 12:14:45 PDT 2017', newVal:''}
5. ValueChange{globalId:'FruitIface/01', property:'compareId', oldVal:'01', newVal:''}
对多个 class 使用相同的 @TypeName 是一种滥用,其原因与对多个 Java class 使用相同的 class 名称一样。
在这种情况下,JaVers 应该抛出异常,而不是因为 JaVers 类型系统变得混乱,你得到的是随机结果。
在当前版本的JaVers 中,即使Apple 和Oranges 都实现了Fruit 接口,也不能将它们进行比较。
JaVers 匹配具有相同 GlobalId
的对象并进行比较。
当您拥有 ID 为 1 的 Apple 和 ID 为 1 的 Orange 时,它们的 GlobalId 为 Apple#1
和 Orange#1
,因此它们不会作为同一对象的两个版本进行匹配。
我正在使用 javers (https://javers.org/) 并尝试比较实现相同接口的两个对象。例如,我用苹果和橙子进行了测试。 Apples to Apples 工作正常,但不是 Apples to Oranges。似乎 运行 比较但没有获得新值。
如果我有一个 Fruit super class 和 apples and oranges 扩展它但没有接口运气,这工作正常。 任何熟悉此 API 的人都可以为我指明正确的方向。
型号代码如下:
@TypeName("FruitIface")
@Entity
public interface FruitIface {
public final static String SIZE_SMALL = "Small";
public final static String SIZE_LARGE = "Large";
public final static String CONDITION_RIPE = "Ripe";
public final static String CONDITION_NOT_RIPE = "Not Ripe";
public String getSize();
public String getCondition();
public Double getWeight();
public Date getSellBy();
}
@TypeName("FruitIface")
@Entity
public class Apple implements FruitIface {
private String size;
private String condition;
private Double weight;
private Date sellBy;
@Id
private String compareId;
public Apple (String id,String size, String condition, Double weight, Date sellBy){
this.compareId = id;
this.size = size;
this.condition = condition;
this.weight = weight;
this.sellBy = sellBy;
}
....
}
@TypeName("FruitIface")
@Entity
public class Orange implements FruitIface {
@PropertyName("size")
private String size;
private String condition;
private Double weight;
private Date sellBy;
@Id
private String compareId;
public Orange (String id, String size, String condition, Double weight, Date sellBy){
this.compareId = id;
this.size = size;
this.condition = condition;
this.weight = weight;
this.sellBy = sellBy;
}
....
}
测试用例:
@Test public void testCompareAppleToAppleIface() {
Apple appleOne = new Apple("01",FruitIface.SIZE_LARGE,FruitIface.CONDITION_RIPE, 0.3, new Date());
Apple appleTwo = new Apple("01",FruitIface.SIZE_SMALL,FruitIface.CONDITION_RIPE, 0.2, new Date());
LOGGER.info("\n\nComparing apples to apples...");
Diff diff = javers.compare(appleOne, appleTwo);
LOGGER.info("diff: " + diff);
}
@Test public void testCompareAppleAndOrangeIface() {
Apple apple = new Apple("01",FruitIface.SIZE_LARGE,FruitIface.CONDITION_RIPE, 0.3, new Date()); //(String size, String condition, Double weight, Date sellBy)
Orange orange = new Orange("01",FruitIface.SIZE_SMALL,FruitIface.CONDITION_RIPE, 0.2, new Date());
LOGGER.info("\n\nComparing apples and oranges IFace...");
Diff diff = javers.compare(apple, orange);
LOGGER.info("diff: " + diff);
}
结果:
Comparing apples to apples...
[main] INFO xxx.compare.test.JaversCompareTestIface - diff: Diff:
1. ValueChange{globalId:'FruitIface/01', property:'size', oldVal:'Large', newVal:'Small'}
2. ValueChange{globalId:'FruitIface/01', property:'weight', oldVal:'0.3', newVal:'0.2'}
Comparing apples and oranges IFace...
[main] INFO xxx.compare.test.JaversCompareTestIface - diff: Diff:
1. ValueChange{globalId:'FruitIface/01', property:'size', oldVal:'Large', newVal:''}
2. ValueChange{globalId:'FruitIface/01', property:'condition', oldVal:'Ripe', newVal:''}
3. ValueChange{globalId:'FruitIface/01', property:'weight', oldVal:'0.3', newVal:''}
4. ValueChange{globalId:'FruitIface/01', property:'sellBy', oldVal:'Thu Aug 10 12:14:45 PDT 2017', newVal:''}
5. ValueChange{globalId:'FruitIface/01', property:'compareId', oldVal:'01', newVal:''}
对多个 class 使用相同的 @TypeName 是一种滥用,其原因与对多个 Java class 使用相同的 class 名称一样。
在这种情况下,JaVers 应该抛出异常,而不是因为 JaVers 类型系统变得混乱,你得到的是随机结果。
在当前版本的JaVers 中,即使Apple 和Oranges 都实现了Fruit 接口,也不能将它们进行比较。
JaVers 匹配具有相同 GlobalId
的对象并进行比较。
当您拥有 ID 为 1 的 Apple 和 ID 为 1 的 Orange 时,它们的 GlobalId 为 Apple#1
和 Orange#1
,因此它们不会作为同一对象的两个版本进行匹配。