2

我想使用 JaVers 来跟踪我的 Java 对象的更改。基本示例运行良好,但我无法检测存储在集合中的对象的更改。

如果我扩展ChangeLogExample.class示例以更改例如其中一个下级:

public static void main(String[] args) {

    Javers javers = JaversBuilder.javers().build();
    Employee bob = new Employee("Bob", 9_000, "Scrum master" );
    javers.commit("hr.manager", bob);

    // do some changes and commit
    bob.setPosition("Team Lead");
    bob.setSalary(11_000);
    javers.commit("hr.director", bob);

    bob.addSubordinates(new Employee("Trainee One"), new Employee("Trainee Two"));
    javers.commit("hr.manager", bob);

    bob.getSubordinates().get(0).setAge(42); // <<<< This is the change I want to detect
    javers.commit("hr.manager", bob); 

    // when:
    List<Change> changes = javers.findChanges(
        QueryBuilder.byInstanceId("Bob", Employee.class).withChildValueObjects().build());
    String changeLog = javers.processChangeList(changes, new SimpleTextChangeLog());

    // then:
    System.out.println(changeLog);
}

这是打印的更改日志:

commit 3.0, author: hr.manager, 2017-06-06 11:17:17
  changed object: Employee/Bob
    list changed on 'subordinates' property: [(0).added:'Employee/Trainee One', (1).added:'Employee/Trainee Two']
commit 2.0, author: hr.director, 2017-06-06 11:17:17
  changed object: Employee/Bob
    value changed on 'position' property: 'Scrum master' -> 'Team Lead'
    value changed on 'salary' property: '9000' -> '11000'

因此,对第一个下属的年龄的更改不会显示在更改日志中。

使用withChildValueObjects()并没有什么不同。

当我分别将更改提交给 Employee 实例时,我得到了对受训者年龄的更改,但这不是我所期望的(也不是我想要的)。

所以我的问题是:如何在 ChangeLog 中显示对年龄的更改?


我正在使用 JaVers 3.2.0

该类Employee与 JaVers 示例相同:https ://github.com/javers/javers/tree/master/javers-core/src/test/java/org/javers/core/examples/model

main()方法只是来自https://github.com/javers/javers/blob/master/javers-core/src/test/java/org/javers/core/examples/ChangeLogExample.java的测试

4

1 回答 1

2

好的,这里有几个问题。首先,Empolyee对象被映射为Entities. 所以在 JaVers 中,它们之间没有父/子关系(实际上是任何类型的关系)。这就是withChildValueObjects()过滤器在这里不适用的原因。它仅适用于ValueObjects拥有者Entities,请参阅http://javers.org/documentation/jql-examples/#child-value-objects-filter

不过,有两种方法可以改进您的查询。

  1. 直接询问您要跟踪的实体实例。

  2. 将新的 Shadow API 与 Query Scopes 一起使用,请参阅http://javers.org/documentation/jql-examples/#query-for-shadows 这是一项新功能,将在该功能中进行改进。如果查询将选择两个实体的快照,则您已经可以使用它。

请参见下面的代码:

def "should ... "(){
  given:
  Javers javers = JaversBuilder.javers().build()
  Employee bob = new Employee("Bob", 9_000, "Scrum master" )
  javers.commit("hr.manager", bob)

  // do some changes and commit
  bob.setPosition("Team Lead")
  bob.setSalary(11_000)
  javers.commit("hr.director", bob)

  bob.addSubordinates(new Employee("Trainee One"), new Employee("Trainee Two"))
  javers.commit("hr.manager", bob)

  bob.getSubordinates().get(0).setAge(42) // <<<< This is the change I want to detect
  bob.salary++ // !
  javers.commit("hr.manager", bob)

  when: "ask for the the right Entity instance"
  List changes = javers.findChanges(
          QueryBuilder.byInstanceId("Trainee One", Employee.class).build())

  then:
  println( javers.processChangeList(changes, new SimpleTextChangeLog()) )
  true

  when: "use the new Shadows"
  List shadows = javers.findShadows(
          QueryBuilder.byInstanceId("Bob", Employee.class)
                      .withShadowScopeDeep().build())

  then:
  shadows.each {
      assert it.get() instanceof Employee
  }
  Employee lastBobShadow = shadows[0].get()
  assert shadows[0].commitMetadata.id.majorId == 4
  assert lastBobShadow.subordinates[0].name == "Trainee One"
  assert lastBobShadow.subordinates[0].age == 42
}
于 2017-06-08T13:48:00.133 回答