Hibernate 将enver添加到现有数据库

Hibernate 将enver添加到现有数据库,hibernate,hibernate-envers,Hibernate,Hibernate Envers,我在生产中有一个基于Hibernate的应用程序,有一个大型数据库。我需要在这个应用程序中向两个实体(两个表)添加审计,我决定使用Envers 对于每次插入、更新或删除,Envers都会向实体的审核表中添加一条新记录 如果从应用程序一开始就支持Envers,那么审计表将在实体创建(INSERT)时填充 Envers文档非常精简,没有提到任何关于将Envers添加到现有应用程序的内容 如果我简单地添加Envers支持并创建相应的审计表,它们将开始为空,因此当我更新现有实体时,Envers将向审计表

我在生产中有一个基于Hibernate的应用程序,有一个大型数据库。我需要在这个应用程序中向两个实体(两个表)添加审计,我决定使用Envers

对于每次插入、更新或删除,Envers都会向实体的审核表中添加一条新记录

如果从应用程序一开始就支持Envers,那么审计表将在实体创建(INSERT)时填充

Envers文档非常精简,没有提到任何关于将Envers添加到现有应用程序的内容

如果我简单地添加Envers支持并创建相应的审计表,它们将开始为空,因此当我更新现有实体时,Envers将向审计表添加一条记录新值的记录,但我将丢失以前的值


如何将Envers支持添加到具有现有数据库的应用程序中?

目前没有内置的解决方案

“正确”的方法是编写SQL脚本(或手动创建)一个“0”修订版,并为每个现有实体插入绑定到该修订版的审核记录


事实上,这是一个非常普遍要求的功能,所以如果你想贡献,它将是最受欢迎的

您需要手动插入。差不多

INSERT INTO z_envers_revisions (ID, timestamp, user_id, user_name) values (1, round((sysdate - to_date('19700101','YYYYMMDD')) * 86400000) , 42, 'UserName');

INSERT INTO z_Table1(rev, revtype, id, description, name) select 1 as rev, 0 as revtype, id, description, name from Table1;
INSERT INTO z_Table2(rev, revtype, id, description, name) select 1 as rev, 0 as revtype, id, description, name from Table2;

我在这里用z作为审计表的前缀,使其更短

就envers而言,基本用例是记录实体的完整审计(我们希望通过@Audited注释记录的参数)。对于您提到的情况,可能会适当添加新实体,但对于现有实体,则会出现问题,因为审计表中没有修订

让我们借助一个场景来解决这个问题:

假设我们考虑的实体是用户。现在创建的用于观察历史的表是users\u audit。除此之外,revinfo还将用于观察和记录给定记录的所有变化

问题首先出现了,因为每当有更新时,持久化层都无法找到修订记录。因此,要修复它,所有现有条目都需要存在于表中,并且与revinfo表的外键映射不应中断。因此,需要做两件事:

  • 在revinfo表中插入临时值,以便rev可以用作外键
  • 将数据从用户表复制到users\u audit 示例Liquibase文件可以如下所示:

        CREATE TABLE `revinfo` (
          `rev` int(11) NOT NULL AUTO_INCREMENT,
          `revtstmp` bigint(20) DEFAULT NULL,
          PRIMARY KEY (`rev`)
        ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
        INSERT INTO `revinfo` (`revtstmp`) select updated_at from users u;
    
        SET @position := 0;
    
        insert into users_audit (
        rev,
        revtype,
        id,
        name,
        type,
        mobile_number,
        password,
        parent_id,
        profile_image_uri,
        is_active,
        created_at,
        updated_at
        ) select @position := @position +1, 0,
        id,
        name,
        type,
        mobile_number,
        password,
        parent_id,
        profile_image_uri,
        is_active,
        created_at,
        updated_at from us
    

    由于修订是全局性的,而不是特定实体的本地修订,我担心添加影响所有实体的“0”修订会中断对以前修订的查询,因为当我查询“0”修订时,它会尝试加载整个数据库,这不是一个问题吗?@DanielSerodio Adamw是正确的。您必须为现有数据库添加版本0并从该版本开始。如果当前没有审核,您如何查找以前的修订版本?@RNJ由于您在我的上述评论后很快回复,我不确定您是否看到了该评论(关于全局修订)。你认为那会是个问题吗?@DanielSerodio我认为你是对的。但是你会这么做吗?或者在给定的修订版中查询特定的表?那个s是我目前使用它的方式。@RNJ当然,我不会查询“rev.0中的所有内容”,但我担心查询“实体E的上一个版本”也会试图获取其他实体。我想我得在测试环境中试一下。嗨!你的问题解决了吗?我也有同样的问题…不,我在Envers上使用了,在INSERT和UPDATE数据库触发器上使用了