【问题标题】:Storing historical data with Java and Hibernate使用 Java 和 Hibernate 存储历史数据
【发布时间】:2010-11-30 18:53:41
【问题描述】:

这是关于历史数据处理的问题。 假设你有一个 MyClass 类,如下所示:

class MyClass {
    String field1;
    Integer field2;
    Long field3;

    getField1() {...}
    setField1(String ...) {...}

    ...
}

现在,假设我需要让 MyClass 能够存储和检索旧数据,那么最好的方法是什么?
要求也是通过 Hibernate 持久化类。 每个“实体”最多有两个表:只有一个表或一个表用于“连续性”类(表示随时间演变的实体),另一个表用于历史数据(建议here
请注意,我必须能够为字段的值分配任意有效时间。

这个类应该有一个类似的接口:

class MyClass {
    // how to store the fields????

    getField1At(Instant i) {...}
    setField1At(Instant i, String ...) {...}

    ...
}

我目前正在使用JTemporal 库,它有一个TemporalAttribute<T> 类,就像一张地图:您可以执行T myAttr.get(Instant i) 之类的操作来在 Instant i 上获取 myAttr 的版本。我知道如何使用 Hibernate 将 TemporalAttribute 持久化在表中(这很简单:我持久化 TemporalAttribute 使用的 SortedMap,您会得到一个包含开始和结束有效时间以及属性值的表)。
真正的问题是这里我们有多个属性。
我有一个解决方案,但不清楚,我想听听你的想法。

【问题讨论】:

    标签: java database hibernate design-patterns class-design


    【解决方案1】:

    你的项目让我想起了Hibernate Envers

    Envers 项目旨在实现轻松 审计持久类。全部 你必须做的是注释你的 持久类或它的一些 您要审核的属性, 与@Audited。对于每一个被审计的 实体,将创建一个表,其中 将保存所做更改的历史记录 到实体。然后您可以检索 并且查询历史数据不多 努力。

    • 选择您要审核的内容(基于每个属性)
    • 制作您自己的修订实体(存储修订号、作者、时间戳等信息...)

    为此使用 Hibernate Envers 将实体和修订数据(在数据库和您的代码中)解耦。

    【讨论】:

    • 我阅读了 Envers 手册,但我无法理解是否可以为修订分配开始和结束有效时间,而不是让 Envers 自行分配。这就是我需要的,因为我不仅需要存储修订,还需要设置修订的有效时间。
    • 您可以实现自己的修订实体(请参阅docs.jboss.org/envers/docs/index.html#revisionlog)并添加自定义时间戳。这就是你要找的吗?
    • 据我所知,如果我将有效日期插入到附加修订数据中,我无法在 Envers 查询中指定它们(我对此并不完全确定)。我正在研究 Envers (jboss.org/envers/downloads/envers_seam_demo.zip) 提供的双时态数据库的代码,我发现这些字段属于“普通”类,尽管示例代码已经很老了。但是有一个更大的问题(来自您的链接的引用):“由于修订是全球性的,您最多可以拥有一个修订实体” - 而我需要“本地”数据,即与特定实体的修订相关的数据
    • 目前,我已经能够使用 Envers 检索旧数据,并将 vt_begin(有效时间开始)和 vt_end 添加到我的班级。但是,据我所知,Envers 一次只考虑一个修订,所以如果我不检查旧修订是否存在等于我设置的内容,我会有重复(我不能有重叠的时期: 特定 id 和 (vt_begin - vt_end)period 只能存在一行。我正在试验,我会尽快通知您
    • 非常有趣。事实上,我不知道 Envers 是否能满足您的要求(让 Envers 去做不应该做的事情并不是一个好主意)。随时通知我们!
    【解决方案2】:

    您只需将版本号添加到您的域类即可执行此类操作。我做了这样的事情,其中​​ Id 是 db 分配的编号和版本号之间的组合,但我建议不要这样做。使用一个普通的代理键,如果你真的想要,将 [id, version] 元组设为自然键。

    您实际上可以通过这种方式对整个对象图进行版本控制,只需确保图上所有元素的版本号相同即可。然后,您可以轻松地返回到任何以前的版本。

    您应该编写大量服务测试以确保管理版本的代码的完整性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 2021-09-19
      • 2023-04-06
      • 2021-03-17
      相关资源
      最近更新 更多