我正在考虑从自我实现的版本控制解决方案切换到Hibernate Envers,但我还不太确定。我已经阅读了很多关于它的内容,但我关注架构更改以及Envers在根据旧架构对数据进行历史记录后如何处理它们。
您在这方面与Envers有什么经历?如何使用Envers处理架构更改和现有数据?
更新1:
这不仅仅是从表中添加删除简单列,而是例如将简单的Forein-Key-Relationship更改为具有两个1:n关系的单独实体(具有属性列的M2M。这是数据模型中的逻辑"更改。当您如何处理时使用Envers时,根据旧模型已有历史数据?是否有其他方法可以手动编写sql脚本并将其转换为新的表示形式?
答案 0 :(得分:4)
根据我的经验,Envers只是将实体表中的每个字段复制到审计表中。审计表中复制的字段对它们没有约束,包括可空性和外键约束,因此在实际表上添加或删除此类约束没有问题。您添加到实体的任何类型的关系都只是在Envers下添加的新审核列和/或表,您可以在历史背景下正确解释它们。
对于您的示例,如果我理解正确,从基于连接列的关系切换到基于连接表的关系,您只需将旧连接列与连接表共存,并在此处在转换中,前者将不再支持后者。您的历史将被完全保留,包括您进行此切换的事实。如果您希望所有旧数据都适合审计表中的新模型,则由您来完成迁移。
答案 1 :(得分:2)
修改现有架构不应该有问题,因为Envers依靠您的@Entities来创建审计表。因此,如果您在现有表中添加或删除列,只要此更改反映在您的@Entity / @Audited JavaBean中,就应该没问题。
答案 2 :(得分:1)
Envers的外键重构应该没问题。由于Envers甚至为一对多关系创建了连接表,因此应该直接将其更改为多对多关系。我从official document中提取了一个段落:
9.3。 @一对多+ @ JoinColumn
使用这两个注释映射集合时,Hibernate 不生成连接表。但是,Envers必须这样做 当您阅读相关实体所具有的修订时 改变了,你不会得到错误的结果。
为了能够命名附加连接表,有一个特殊的 注释:@AuditJoinTable,它与JPA的语义相似 @JoinTable。
一个特例是与@ OneToMany + @ JoinColumn映射的关系 一边和@ ManyToOne + @ JoinColumn(insertable = false, 很多方面,updatable = false)。事实上,这种关系 双向,但拥有方是集合(见此处)。
要正确审核与Envers的此类关系,您可以使用 @AuditMappedBy注释。它使您可以指定反向 property(使用mappedBy元素)。如果是索引集合, 索引列也必须映射在引用的实体中(使用 @Column(insertable = false,updatable = false),并使用指定 positionMappedBy。此注释仅影响Envers的方式 作品。请注意,注释是实验性的,可能会发生变化 在将来。