首页 文章

使用Hibernate Envers进行审计跟踪:如何仅跟踪实体上的选定更改?

提问于
浏览
2

我已经使用hibernate envers为我的实体实现了审计跟踪,它工作正常 . 任何更改(插入,更新,删除)都存储在_AUD表中 .

现在,我想在一个实体属性仅更改时扩展我的审计和跟踪更改 . 我想将更改存储到附加表 . 除了跟踪实体中所有更改的现有TABLE_AUD表之外,我还需要第二个表TABLE_AUD2,它将仅基于一个实体属性跟踪更改 . 重要的是:事物与同一个实体有关 .

在envers中有可能吗?您可以建议实施这样的要求吗?

1 回答

  • 5

    Hibernate envers通过在属性或实体上使用 @Audited(withModifiedFlag=true) (或将 org.hibernate.envers.global_with_modified_flag 配置属性设置为true)来提供属性级别的实体跟踪 . 此全局开关将导致为所有已审计实体中的所有审计属性添加修改标志 . 这将为 _AUD 表中的每个审计字段生成一个额外的 _MOD 字段,该字段为审计字段提供标记,以标识在特定修订版本中已修改的字段 . 例如:对于所有属性 -

    @Entity
    @Table(name="EMPLOYEE")
    @Audited(withModifiedFlag=true)
    public class Employee {
    
        @Id
        @Column(name="ID")
        @GeneratedValue
        private Integer id;
    
        @Column(name="FIRSTNAME")
        private String firstname;
    
        @Column(name="LASTNAME")
        private String lastname;
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getFirstname() {
            return firstname;
        }
        public String getLastname() {
            return lastname;
        }
        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }
        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
    }
    

    或者像firstName这样的特定属性

    @Entity
    @Table(name="EMPLOYEE")
    public class Employee {
    
        @Id
        @Column(name="ID")
        @GeneratedValue
        private Integer id;
    
        @Audited(withModifiedFlag=true)
        @Column(name="FIRSTNAME")
        private String firstname;
    
        @Column(name="LASTNAME")
        private String lastname;
    
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getFirstname() {
            return firstname;
        }
        public String getLastname() {
            return lastname;
        }
        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }
        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
    }
    

    使用与属性对应的附加 _MOD 字段,我们可以识别使用 @Auditied 注释的属性已更改的特定修订 .

    AuditReader reader = AuditReaderFactory.get(this.sessionFactory.getCurrentSession());
    List<Object[]> objects =  reader.createQuery().forRevisionsOfEntity(Employee.class, false, true)
                    .add(AuditEntity.id().eq(id))
                    .add(AuditEntity.property("firstName").hasChanged()).getResultList();
    

    这将仅返回' Employee ' entity in which ' firstName '的修订版本 . 从上面代码中的 List<Object[]> 开始,我们可以获得每个版本的' Employee ' entity, ' DefaultRevisionEntity '实体和 RevisonType . 下面的代码片段详细说明了获取版本号的示例 .

    List<Number> revisions = new ArrayList<Number>();  
    for(Object[] ob: objects){
                revisions.add(((DefaultRevisionEntity) ob[1]).getId());
            }
    

相关问题