我在生产中有一个基于Hibernate的应用程序,有一个大型数据库。我需要在此应用程序中向两个实体(两个表)添加审计,我决定使用Envers。
对于每个INSERT,UPDATE或DELETE,Envers都会向实体的审计表添加新记录。
如果我从应用程序启动时获得了Envers支持,则会在创建实体(INSERT)时填充审计表。
Envers文档非常简洁,并未提及有关向现有应用程序添加Envers的任何内容。
如果我只是添加Envers支持并创建相应的审计表,它们将从空开始,所以当我更新现有实体时,Envers会在记录新值的审计表中添加一条记录,但我会丢失之前的值。
如何向具有现有数据库的应用程序添加Envers支持?
答案 0 :(得分:2)
目前还没有内置的解决方案。
"正确"方法是编写一个SQL脚本(或手动创建)" 0"修订,以及为每个现有实体绑定到该修订的插入审计记录。
实际上,这是一个非常常见的功能,所以如果你想做出贡献,那将是非常受欢迎的!
答案 1 :(得分: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;
我在这里使用z为我的审核表做了前缀以缩短
答案 2 :(得分:0)
就envers而言,基本用例是记录实体的完整审计(我们希望通过@Audited注释的参数)。对于您提到的情况,可能会正确添加新实体,但对于现有实体,它会产生问题,因为审计表中不存在修订。
让我们借助一个场景来解决这个问题:
假设我们考虑的实体是用户。现在创建的用于观察历史记录的表格是 users_audit 。除此之外, revinfo 也将用于观察和记录给定记录的所有变化。
首先出现问题,因为只要有更新,持久层就无法找到修订记录。因此,为了解决这个问题,需要在表中存在所有现有条目,并且不应该破坏与revinfo表的外键映射。因此,需要做两件事:
示例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