为基于Hibernate的应用程序实现数据历史/版本控制解决方案(带有扭曲)

Jan*_*nne 6 java mysql versioning hibernate datahistory

首先是基本事实:Java webapp,Spring,Hibernate,MySQL.

情况是我有一个复杂的对象模型,例如汽车.它由许多物体(发动机,轮胎......)组成,它们之间具有多对一和一对多的关系.

现在有很多车,不时有人检查汽车并创建检查报告.报告指的是汽车的许多部件,显示其属性等.

到目前为止,系统还没有支持在汽车进入系统后更新汽车及其零件属性的能力.这意味着如果底盘颜色或轮胎数量发生变化,旧报告将反映出这种变化,这不是我们想要的.

那么,现在已经请求了这个功能.汽车及其零件需要可修改,并且必须创建版本历史记录.旧报告需要参考旧版本的零件及其值.

我一直在关注" 慢慢改变尺寸 ",似乎汽车及其零件的版本化可以通过Type 6方法完成.

我遇到麻烦(可能是由于我有限的Hibernate经验)的事情(扭曲)是这样的:

如何使用Hibernate组合我的Report实例,以便它们引用汽车每个部分的正确版本?报告有一个日期,汽车零件的每个版本都有有效的日期范围,所以我想我可以用一些复杂的HQL/SQL来做.但是有没有更简单,更自动的方式来使用Hibernate?

Boz*_*zho 6

您可以查看JBoss envers来对对象进行版本控制.我不确定它是否适合您的用例,但请看一下.


Fri*_*ben 1

我已经在 Hibernate 中使用了您建议的方法(类型 6),它对我来说效果很好。报告的查询确实变得有点复杂,但也没有那么复杂,因为所有查询都需要相同的子句(例如 ' and :reportTime >= x.startTime and (:reportTime < x.endTime or x.endTime is null )')。

我为支持具有 2 个属性(例如 startTime 和 endTime)的方法的实体创建了一个接口和一个基类(仅父类不是时间的时间子类需要接口),并为使用时间实体的 DAO 创建了一个基类有一些经常需要的功能。我在这个基础 DAO 中放入的东西:

  1. 防止更改 startTime 已过的实例(将 endTime 设置为未来时间除外)
  2. 如果添加了新实例(例如oldInstance.endTime = newInstance.startTime),则自动关闭(即填充endTime)前一个实例
  3. 添加标准子句以在查询 HQL 查询时选择当前实体。
  4. 如果由于某种原因同时找到两个有效的实例/版本,则处理重复项(我按“startTime desc”对查询进行排序,并且仅返回第一个)

我发现它真正混乱的唯一部分是使用也针对数据库运行的普通 SQL 查询,其中在连接表或子选择中需要额外的子句。