如何将 hibernate envers 主键的 ddl 恢复为与版本 5 相同的行为

问题描述 投票:0回答:1

我正在升级到 hibernate 6。我们在一些具有复杂域和大量数据的服务上广泛使用 envers。我们使用 liquibase 生成数据库迁移脚本。

我很惊讶地发现 liquibase 在升级后生成了大量数据库变更集...所有这些变更都与“_aud”表相关,删除并重新创建主键:在 hibernate 5 中,审核表主键中字段的顺序是“id,rev”,在 hibernate 6 中是“rev,id”。

Liquibase 发现这种差异会生成尝试解决所有这些问题的变更集,但它并不完整...(删除外键中使用的主键不起作用)...这意味着需要将 2000 多行文件手动修复...

修复有效的东西需要大量工作,更改将需要很长时间才能修复,而且还要在产品中执行,并且可能会对我无法衡量的性能产生影响......所以我真的很喜欢推迟到稍后的时间。

有没有办法恢复到 hibernate 5 的旧行为,比如配置之类的? (我看了,但什么也没发现)


这是一个用于说明行为的简单实体:

@Entity
@Audited
public class MyEntity {

    @Id
    private Long id;

    private String name;
}

这是在 hibernate 5.6.15.Final 中生成的:

  <changeSet author="snussbaumer (generated)" id="1693555682159-2">
    <createTable tableName="my_entity_aud">
      <column name="id" type="BIGINT">
        <constraints nullable="false" primaryKey="true" primaryKeyName="my_entity_audPK" />
      </column>
      <column name="rev" type="INT">
        <constraints nullable="false" primaryKey="true" primaryKeyName="my_entity_audPK" />
      </column>
      <column name="revtype" type="TINYINT" />
      <column name="name" type="VARCHAR(255)" />
    </createTable>
  </changeSet>

这就是 hibernate 6.2.7.Final :

  <changeSet author="snussbaumer (generated)" id="1693555682159-2">
    <createTable tableName="my_entity_aud">
      <column name="id" type="BIGINT">
        <constraints nullable="false" />
      </column>
      <column name="rev" type="INT">
        <constraints nullable="false" />
      </column>
      <column name="revtype" type="TINYINT" />
      <column name="name" type="VARCHAR(255)" />
    </createTable>
  </changeSet>
  <changeSet author="snussbaumer (generated)" id="1693555682159-4">
    <addPrimaryKey columnNames="rev, id" constraintName="my_entity_audPK" tableName="my_entity_aud" />
  </changeSet>
hibernate hibernate-envers hibernate-6.x
1个回答
0
投票

经过相当多的挖掘,“问题”来自于这个相当大的提交:https://github.com/hibernate/hibernate-orm/commit/fb882f56f313e09889c362952e489ec26d527765

现在键按名称排序,就是这样......没有配置可以更改它。这确实忽略了对性能的任何考虑(但这也许留给库的用户来做)。

一些解决方法:

  • 使用“org.hibernate.envers.revisionFieldName”属性。比较区分大小写。使用小写的“rev”(而不是默认的大写“REV”)做了一些工作:我得到“id,rev”,而不是“REV,id”。这对于简单方案来说是一个进步,但对于集合表来说,这将转速放在其他列之间的任何位置,而它应该是第一个,所以对于最简单的情况来说还不够。
  • 如果使用 liquibase 实现一个 ObjectChangeFilter,它会删除仅适用于审核表的主键列顺序的更改。这解决了问题,但新审计实体的主键列顺序将与使用 hibernate 5 创建的顺序不同
  • 如果使用 liquibase 扩展您正在使用的 liquibase.database.Database,请在调用父级 buildMetadataFromPath 后对 buildMetadataFromPath 中的列重新排序。
© www.soinside.com 2019 - 2024. All rights reserved.