比较与 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#1Orange#1,因此它们不会作为同一对象的两个版本进行匹配。