6

首先是基本事实:Java webapp、Spring、Hibernate、MySQL。

情况是我有一个复杂的对象模型,例如Car。它由许多对象(引擎、轮胎……)组成,它们之间具有多对一和一对多的关系。

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

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

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

我一直在研究“缓慢变化的尺寸”,似乎汽车及其零件的版本控制可以通过 Type 6 方法完成。

我无法弄清楚的事情(扭曲)(可能是由于我有限的 Hibernate 经验)是这样的:

如何使用 Hibernate 组装我的 Report 实例,以便它们引用汽车每个部分的正确版本?这些报告有一个日期,并且每个版本的汽车零件在有效时都会有日期范围,所以我想我可以使用一些复杂的 HQL/SQL 来完成。但是有没有更简单、更自动化的方式来使用 Hibernate 呢?

4

3 回答 3

7

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

于 2009-12-22T10:59:07.327 回答
1

MySQL 支持触发器。设置触发器,以便每当更改行时,触发器将行复制到“存档”表中,以及时间戳。这样,所有以前的数据版本都得到维护,可以针对这些数据版本运行报告。

于 2009-12-22T10:19:58.383 回答
1

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

我为支持这种方法的实体创建了一个接口和一个基类(只有父级不是临时的临时子类才需要接口)(例如 startTime 和 endTime),以及一个用于使用临时实体的 DAO 的基类有一些经常需要的功能。我在这个基础 DAO 中放入的东西:

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

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

于 2009-12-22T13:08:01.533 回答