使用 Java 和 Hibernate 存储历史数据
这是历史数据处理的问题。 假设您有一个如下所示的类 MyClass:
class MyClass {
String field1;
Integer field2;
Long field3;
getField1() {...}
setField1(String ...) {...}
...
}
现在,假设我需要使 MyClass 能够存储和检索旧数据,那么最好的方法是什么?
要求也是通过 Hibernate 保留这些类。 每个“实体”最多有两个表:只有一个表或一个表用于“连续性”类(代表随时间演变的实体),另一个表用于历史数据(正如此处建议的那样)
请注意,我必须能够为字段的值分配任意有效时间。
该类应该具有如下接口:
class MyClass {
// how to store the fields????
getField1At(Instant i) {...}
setField1At(Instant i, String ...) {...}
...
}
我当前正在使用 JTemporal 库,并且它有一个 TemporalAttribute
类,它就像一个地图:您可以执行诸如 T myAttr.get(Instant i)
之类的操作来获取 Instant i 处 myAttr 的版本。我知道如何使用 Hibernate 将 TemporalAttribute 保存在表中(很简单:我保存 TemporalAttribute 使用的 SortedMap,然后您将获得一个包含开始和结束有效时间以及属性值的表)。
真正的问题是这里我们有多个属性。
我心里有一个解决方案,但还不清楚,我想听听您的想法。
This is a problem about historical data handling.
Suppose you have a class MyClass like the following one:
class MyClass {
String field1;
Integer field2;
Long field3;
getField1() {...}
setField1(String ...) {...}
...
}
Now, suppose I need to make MyClass able to store and retrieve old data, what's the best way to do this?
The requirements are to persist the classes through Hibernate, too. And to have at most two tables per "entity": only one table or one table for the "continuity" class (the one which represents the entity which evolves over the time) and another table for the historical data (as it's suggested here)
Please note that I have to be able to assign an arbitrary valid time to the values of the fields.
The class should have an interface like:
class MyClass {
// how to store the fields????
getField1At(Instant i) {...}
setField1At(Instant i, String ...) {...}
...
}
I'm currently using the JTemporal library, and it has a TemporalAttribute<T>
class, which is like a map: you can do things like T myAttr.get(Instant i)
to get the version of myAttr at Instant i. I know how to persist a TemporalAttribute in a table with Hibernate (it's simple: I persist the SortedMap used by the TemporalAttribute and you get a table with start and end valid time and the value of the attribute).
The real problem is that here we have multiple attributes.
I have a solution in mind but it's not clear, and I'd like to hear your ideas.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的项目让我想起了Hibernate Envers。
使用 Hibernate Envers 来实现实体和修订数据的解耦(在数据库和您的数据库中)代码)。
Your project reminds me of Hibernate Envers.
Using Hibernate Envers for this decouples entities and revision data (in database and in your code).
您只需向域类添加版本号即可完成类似的操作。我做了类似的事情,其中 Id 是数据库分配的编号和版本号之间的组合,但我建议不要这样做。使用普通的代理键,如果您确实需要,请将 [id, version] 元组设置为自然键。
实际上,您可以通过这种方式对整个对象图进行版本控制,只需确保图上所有元素的版本号相同即可。然后您可以轻松返回到任何以前的版本。
您应该编写大量服务测试以确保管理版本的代码的完整性。
You can do something like this simply by adding a version number to your domain class. I did something like this where the Id was a composite between an db assigned number and the version number, but I would advise against that. Use a normal surrogate key, and if you really want, make the [id, version] tuple a natural key.
You can actually version entire object graphs that way, just by ensuring that the version number is the same for all elements on the graph. You can then easily go back to any previous version.
You should write a lot of service tests to insure the integrity of the code that manages the version.