我使用https://github.com/javers/javers/issues/98中描述的类似用例。
在下面的代码中,当我更新依赖对象并提交Employee bob时,我希望依赖的更改从JQL查询中检索QueryBuilder.byInstanceId(1L, Employee.class)
//update dependent's name ( WANT TO TRACK THIS FROM ROOT EMPLOYEE OBJECT)
Dependent aDep = bob.getDependentById(1L);
aDep.setName("Ramsey");
javers.commit("hr.manager", bob);
完整代码:
import lombok.Getter;
import lombok.Setter;
import org.javers.core.Javers;
import org.javers.core.JaversBuilder;
import org.javers.core.changelog.SimpleTextChangeLog;
import org.javers.core.diff.Change;
import org.javers.repository.jql.QueryBuilder;
import org.junit.Test;
import javax.persistence.Id;
import java.util.*;
public class JaversTests {
@Test
public void shouldPrintTextChangeLog() {
// given:
Javers javers = JaversBuilder.javers().build();
//initial employee
Employee bob = new Employee(1L, "Bob", 9_000, "Junior Developer");
javers.commit("hr.manager", bob);
// promoted
bob.setPosition("Senior Developer");
bob.setSalary(11_000);
javers.commit("hr.director", bob);
//add dependents
bob.addDependents(new Dependent(1L, "Ram", "Son"), new Dependent(2L, "Kabita", "Daughter"));
javers.commit("hr.manager", bob);
//update dependent's name ( WANT TO TRACK THIS FROM ROOT EMPLOYEE OBJECT)
Dependent aDep = bob.getDependentById(1L);
aDep.setName("Ramsey");
javers.commit("hr.manager", bob);
List<Change> employeeChanges = javers.findChanges(
QueryBuilder.byInstanceId(1L, Employee.class).withChildValueObjects().build());
String employeeChangeLog = javers.processChangeList(employeeChanges, new SimpleTextChangeLog());
System.out.println(employeeChangeLog);
}
}
@Getter
@Setter
class Employee {
@Id
Long id;
String name;
double salary;
String position;
Set<Dependent> dependents = new HashSet<>();
public Employee(Long id, String name, double salary, String position) {
this.id = id;
this.name = name;
this.salary = salary;
this.position = position;
}
void addDependents(Dependent... dependents) {
getDependents().addAll(new LinkedList(Arrays.asList(dependents)));
}
Dependent getDependentById(Long id) {
for (Dependent dep : getDependents()) {
if (dep.getId() == id) {
return dep;
}
}
return null;
}
}
@Setter
@Getter
class Dependent {
@Id
Long id;
String name;
String relation;
public Dependent(Long id, String name, String relation) {
this.id = id;
this.name = name;
this.relation = relation;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dependent dependent = (Dependent) o;
return Objects.equals(id, dependent.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
我得到了以下输出。这缺少了依赖名称的变化(Ram to Ramsey)。
commit 3.0, author: hr.manager, Oct 3, 2016 12:45:57 PM
changed object: us.sdata.enroll.Employee/1
set changed on 'dependents' property: [added:'us.sdata.enroll.Dependent/2', added:'us.sdata.enroll.Dependent/1']
commit 2.0, author: hr.director, Oct 3, 2016 12:45:57 PM
changed object: us.sdata.enroll.Employee/1
value changed on 'salary' property: '9000.0' -> '11000.0'
value changed on 'position' property: 'Junior Developer' -> 'Senior Developer'
谢谢!
答案 0 :(得分:1)
withChildValueObjects()
过滤器仅适用于子(依赖)ValueObjects和
你有两个类映射为实体(@Id ann存在)。
由于Employee
和Dependent
对象之间没有明确的父子关系,因此JaVers会平等对待它们。
如果将Dependent
映射为ValueObject(删除@Id就足够了),您的测试将通过。
答案 1 :(得分:1)
在这种情况下没有干净的解决方案,因为JaVers JQL不支持实体连接。因此,没有简单的方法来查找实体X的快照,这些快照是从实体Y的快照引用的。 我可以建议的是准备以DDD聚合(Entity及其子ValueObjects)形式塑造的DTO对象,并将这些DTO提交给JaVers而不是原始域对象。我知道这不是一个多变的优雅解决方案。