Javers未报告对象层次结构中的引用更改

时间:2017-09-30 09:18:48

标签: java cas javers

问题陈述

我正在尝试使用Javers 3.5.1报告所提交的更改的能力。似乎只有在它们是原始的情况下才会报告变化;当对象引用在实体的层次结构中发生更改时,不会报告更改。

样品

以下是一个示例:

    Javers javers = JaversBuilder.javers().build();

    RegexRegisteredService svc2 = new RegexRegisteredService();
    // Set a reference to something
    svc2.setUsernameAttributeProvider(new DefaultRegisteredServiceUsernameProvider());
    svc2.setId(345);
    javers.commit("345", svc2);

    // change the reference
    svc2.setUsernameAttributeProvider(new AnonymousRegisteredServiceUsernameAttributeProvider());
    javers.commit("345", svc2);

    List<Change> changes = javers.findChanges(QueryBuilder.byInstanceId("345", 
                               RegexRegisteredService.class).build());
    System.out.println(changes.size());

上述代码段的结果为0.

诊断

进一步的诊断显示包含类中的对象引用获得了自己的id; findChanges()函数仅查看具有该id的包含类/实体,并且不会遍历层次结构以查找其他引用和属性。当InMemoryRepository开始将历史记录中的快照与传递的globalId进行比较时,它只会查看父globalId,而不会查看包含的类列表:

    Iterator it = this.getAll().iterator();

    while(it.hasNext()) {
        CdoSnapshot snapshot = (CdoSnapshot) it.next();
        if (snapshot.getGlobalId().equals(globalId)) {
            filtered.add(snapshot);
        }
    ...

此处,传递的globalIdorg.apereo.cas.services.RegexRegisteredService/345。但是,这个id中的任何内容都没有改变;真正改变的是映射到org.apereo.cas.services.RegexRegisteredService/345#usernameAttributeProvider,它永远不会被检索,因为上面的检查失败了相等的条件。

层次结构是这样的:

public interface RegisteredService {}

public abstract class AbstractService implements RegisteredService {
   // with setters and getters
   private UsernameAttributeProviderInterface usernameAttributeProvider;
}

public class RegexRegisteredService extends AbstractService {}

替代?

这样的事情呢?

    Iterator it = this.getAll().iterator();

    while(it.hasNext()) {
        CdoSnapshot snapshot = (CdoSnapshot) it.next();
        if (snapshot.getGlobalId().value().startsWith(globalId.value())) {
            filtered.add(snapshot);
        }
    ...

Javers中是否缺少此功能,还是我错过了什么?想知道我是否应该设计自己的存储库类?

2 个答案:

答案 0 :(得分:0)

事实证明我需要做一些非常简单的事情:

final List<Change> changes = javers.findChanges(
            QueryBuilder.byInstanceId("345, RegexRegisteredService.class)
                    .withChildValueObjects()
                    .build());

参考: https://javers.org/documentation/jql-examples/#child-value-objects-filter

答案 1 :(得分:0)

您可能已将引用的对象映射为ValueObjects(这是默认值)。在JaVers中,ValueObjects被视为属性容器,它们的类型在比较时并不重要。这反映在GlobalId:

org.apereo.cas.services.RegexRegisteredService/345#usernameAttributeProvider

如果要跟踪类型更改,则需要将引用的对象映射为实体