2013-03-20 116 views
7

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

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

如果我从应用程序的启动获得Envers支持,那么在实体创建(插入)时将会填充审计表。

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

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

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

+0

嗨!你解决了你的问题吗?我也有同样的问题。 – gipinani 2013-08-30 05:22:58

+0

不,我给Envers并使用ON INSERT和ON UPDATE数据库触发器 – 2013-08-30 13:42:53

回答

2

目前没有内置解决方案。

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

其实,这是一个非常普遍的要求,所以如果你想贡献,这将是最受欢迎的!

+0

因为修订是全局的,而不是特定实体的本地,恐怕添加一个“0”影响所有实体的修订版会打破以前的修订版的查询,因为当我查询“0”修订版时,它会尝试加载整个数据库,这不是问题吗? – 2013-03-21 16:36:20

+0

@DanielSerodio Adamw是正确的。您必须添加修订版本0并从现有数据库开始。如果目前没有审计,你如何能找出以前的修订版? – RNJ 2013-03-21 16:38:19

+0

@RNJ,因为您在我上面的评论后迅速回复,我不确定您是否看到该评论(关于全局修订)。你认为这会是一个问题吗? – 2013-03-21 16:40:08

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我在这里的审计表的东西把它缩短

0

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

让我们破案有场景的帮助:

比方说,我们已经考虑到实体用户。现在创建的表格用于观察历史记录,比方说,users_audit。除此之外,revinfo也将适用于观察和记录对于给定记录的所有变化。

问题首先出现,因为每当有更新时,持久层无法找到修订记录。因此,为了解决这个问题,需要在表中存在所有现有的条目,并且不应该使用revinfo表进行外键映射。因此,需要两件事情要做:

  1. 插入Temp值在revinfo表,以便转可以作为外键
  2. 复制从用户行为数据表到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