使用Java和Hibernate存储历史数据

时间:2010-11-30 18:53:41

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

这是关于历史数据处理的问题。 假设您有一个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)之类的操作来获取myAttr的版本即时通讯我知道如何在带有Hibernate的表中持久保存TemporalAttribute(很简单:我坚持使用TemporalAttribute使用的SortedMap,并获得一个包含开始和结束有效时间以及属性值的表格。) 真正的问题是,这里我们有多个属性 我有一个解决方案,但目前尚不清楚,我想听听你的意见。

2 个答案:

答案 0 :(得分:5)

您的项目让我想起了Hibernate Envers

  

Envers项目旨在实现轻松   审计持久化类。所有   你要做的就是注释你的   持久类或其中的一些   要审核的属性,   与@Audited。对于每个被审计的   实体,将创建一个表,其中   将记录所做的变化   到实体。然后你可以检索   并且没有太多查询历史数据   努力。

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

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

答案 1 :(得分:0)

只需向您的域类添加版本号,即可完成此类操作。我做了类似这样的事情,其中​​Id是数据库分配号码和版本号之间的复合,但我建议不要这样做。使用正常的代理键,如果你真的想要,可以使[id,version]元组成为一个自然键。

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

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