当前位置: 首页 > 知识库问答 >
问题:

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

汪安宁
2023-03-14

我正在试验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;findChange()函数只查看具有该id的包含类/实体,而不会向下遍历层次结构来定位其他引用和属性。当在InMemoryRepository中开始比较从历史记录到传递的globalId的快照时,它只会查看父globalId,不会向下查看包含类的列表:

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

    html" target="_blank">while(it.hasNext()) {
        CdoSnapshot snapshot = (CdoSnapshot) it.next();
        if (snapshot.getGlobalId().equals(globalId)) {
            filtered.add(snapshot);
        }
    ...

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

层次结构是这样的:

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个答案

孔运良
2023-03-14

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

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

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

柳项明
2023-03-14

原来我需要做一些非常简单的事情:

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

参考:https://javers.org/documentation/jql-examples/#child-值对象过滤器

 类似资料:
  • 零售商店的正确模式是什么?公司从商店销售产品。 这似乎违反了我对OOP所知的全部知识。通过层次结构向下传递数据的方法--在对象之间复制参数?我错过了什么?

  • 我想将Nightwatch的页面对象系统用于我们应用程序中使用的UI组件。因为nightwatch有自己的读取/初始化它们的方式,所以我看不到正确扩展/重用它们的方法。 例如,我想要一个“日期字段”的DateInputPageObject。它将识别标签、输入、日期选择器等。 我会在任何带有日期输入字段的页面上使用它。 我还想扩展页面对象。例如,。将为所有模态元素定义选择器-覆盖、容器、关闭按钮等。

  • 问题内容: 我在 .NET for WinRT(C#)中 ,我想将JSON字符串反序列化为,然后将字典值稍后转换为实际类型。JSON字符串可以包含对象层次结构,我也希望在其中包含子对象。 这是应该能够处理的示例JSON: 我尝试使用 DataContractJsonSerializer 这样做: 实际上,这对于第一个级别是可行的,但是 “父母” 只是一个不能强制转换为的对象: 然后,我尝试使用 J

  • 问题内容: 我有一个现有的对象层次结构,其中某些对象具有需要注入的字段。另外,还有一些其他对象是使用Google Guice 构造的,需要注入对先前描述的对象层次结构中某些对象的引用。我该如何用Guice注射? 问题在于,现有层次结构中的对象不是使用Guice构造的,因此默认情况下不受注入过程的约束。当然,有一种方法可以注入到现有的对象实例中,但是它不适用于对象层次结构。 对于那些想知道为什么我不

  • 问题内容: 在“深度”对象层次结构中使用Builder模式的最佳实践是什么?详细地说,我探讨了将Joshua Bloch提出的Builder模式应用于我的XML绑定代码的想法(我使用的是SimpleXML,但是这个问题将适用于任何情况)。我的对象层次结构深达4个级别,具有不同程度的复杂性。我的意思是,在某些级别上,我的对象只有几个属性,而在其他级别上,我最多可以有10个属性。 因此,请考虑以下假设

  • 我想枢轴的数据帧像: 进入具有如下分层列的数据帧: 我尝试了,但它只会给我一个这样的框架: 如何更改列的层次结构?