9

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

对于每个 INSERT、UPDATE 或 DELETE,Envers 都会向实体的审计表中添加一条新记录。

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

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

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

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

4

3 回答 3

3

目前没有内置的解决方案。

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

实际上,这是一个很常见的功能,所以如果你愿意贡献,那将是非常受欢迎的!

于 2013-03-21T16:09:10.420 回答
1

您将需要手动插入。就像是

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;

我在我的审计表前面加上了 az 以使其更短

于 2013-03-21T16:43:57.350 回答
0

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

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

假设我们考虑的实体是users。现在为观察历史而创建的表是users_audit。除此之外,revinfo也将用于观察和记录对给定记录的所有更改。

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

  1. 在 revinfo 表中插入临时值,以便 rev 可以充当外键
  2. 将数据从users表复制到users_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
于 2017-12-01T10:28:17.747 回答