15

我正在考虑从自我实现的版本控制解决方案切换到 Hibernate Envers,但我还不太确定。我已经阅读了很多关于它的内容,但我担心模式更改以及 Envers 在根据旧模式对历史数据进行处理后如何处理它们。

在这方面,您对 Envers 有何经验?您如何使用 Envers 处理架构更改和现有数据?

更新1:

这不仅仅是添加从表中删除简单的列,而是例如将简单的外键关系更改为具有两个 1:n 关系的单独实体(具有属性列的 M2M。这是您的“逻辑”更改数据模型。在使用 Envers 时,如果根据旧模型已经有历史数据,您如何处理?是否有替代手动编写 sql 脚本并将它们转换为新表示的替代方法?

4

3 回答 3

4

根据我的经验,Envers 只是将实体表中的每个字段复制到其审计表中。审计表中复制的字段对它们没有任何约束,包括可空性和外键约束,因此在真实表上添加或删除此类约束没有问题。您添加到实体的任何类型的关系都将只是在 Envers 下添加的新审计列和/或表,您可以在其历史背景下正确解释它们。

对于您的示例,如果我理解正确,从基于连接列的关系切换到基于连接表的关系,您只需让旧连接列与连接表共存,并且在切换点, 前者将不再被填充而有利于后者。您的历史记录将被完全保留,包括您进行此切换的事实。如果您希望所有旧数据都适合审计表中的新模型,则由您来完成迁移。

于 2012-06-04T04:03:40.680 回答
2

修改现有架构应该没有问题,因为 Envers 依赖于您的 @Entities 来创建审计表。因此,如果您从现有表中添加或删除列,只要此更改反映在您的 @Entity / @Audited JavaBean 中,就应该没问题。

于 2011-07-30T23:56:14.970 回答
1

Envers 的外键重构应该没问题。由于 Envers 甚至为一对多关系创建了一个连接表,因此应该直接将其更改为多对多关系。我从官方文档中提取了一段:

9.3. @OneToMany+@JoinColumn

当使用这两个注解映射集合时,Hibernate 不会生成连接表。然而,Envers 必须这样做,这样当您阅读相关实体已更改的修订时,您不会得到错误的结果。

为了能够命名附加的连接表,有一个特殊的注解:@AuditJoinTable,它与 JPA 的 @JoinTable 具有相似的语义。

一种特殊情况是一方面与@OneToMany+@JoinColumn 映射的关系,另一方面是@ManyToOne+@JoinColumn(insertable=false, updatable=false) 映射的关系。这种关系实际上是双向的,但拥有方是集合(参见此处)。

要正确审核与 Envers 的此类关系,您可以使用 @AuditMappedBy 注释。它使您能够指定反向属性(使用 mappedBy 元素)。在索引集合的情况下,索引列也必须映射到引用的实体中(使用@Column(insertable=false, updatable=false),并使用positionMappedBy指定。这个注释只会影响Envers的工作方式。请注意,注释是实验性的,将来可能会改变。

于 2012-06-04T03:35:11.753 回答