# 使用 Hibernate 4 进行审计

> 原文： [https://javabeginnerstutorial.com/hibernate/auditing-with-hibernate-4/](https://javabeginnerstutorial.com/hibernate/auditing-with-hibernate-4/)

在本文中，我将向您简要介绍使用 Hibernate 进行实体审计，或更具体地说，是使用 Hibernate Envers，因为这是 Hibernate 核心的 3.x 版本的一部分。

顺便说一句：Envers 保留用于实体版本控制。

## 我为什么要关心审计？

如果您从事较大的项目（或将来某个时候），则审计将在您的应用中扮演重要角色，以监视谁更改了敏感数据。 有时仅监视谁进行了更改是不够的：您想知道已更改的内容以及哪些值也已更改。

为此，您可以创建自己的自定义解决方案或使用 Hibernate Envers，它是 Hibernate 核心的一部分，提供了开箱即用的功能。

仅提及一个场景：您是汽车零售应用的开发人员。 有人出售一辆豪华轿车的正常价格要低 80% 的汽车，却没人知道谁改变了价格。 最后，您会感到后悔，因为您没有监视，因此必须在很短的时间内解决此问题。

如果听起来很绝望，并且您想袖手旁观，请继续阅读。

## Hibernate Envers 的易用性

要使 Hibernate Envers 正常工作，您需要将其导入到类路径中，或者如果使用 Maven，则将其作为依赖项：

```java
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-envers</artifactId>
    <version>4.3.10.Final</version>
 </dependency>
```

如果您的类路径上有 Envers，只需在要审计的实体或属性上使用 [[受电子邮件保护]](/cdn-cgi/l/email-protection) 注解：

```java
@Entity
 @Table(name = "BOOKS")
 @Audited
 public class Book {
 // ... the body of the entity
 }
```

在这种情况下，Hibernate 自动管理实体的版本控制。 它将创建一个包含实体表名称和后缀`_AUD`的表。 在此示例`BOOKS_AUD`中，它在那里存储实体的所有字段以及两个额外的列：`REVTYPE`和`REV`。

`REVTYPE`是修订版本的类型，它可以采用值`add`，`mod`，`del`分别插入，修改或删除。

`REV`字段保存所存储条目的修订号。

如果仅使用`@Audited`注释对实体的一个或某些字段进行注释，则`*_AUD`表将包含两个额外的审计字段，即使用`@Audited`注释的字段和实体的 ID。

Hibernate 创建了一个称为`REVINFO`的额外表，其中在实体发生更改时`REV`编号与时间戳进行映射。

## 自定义修订表

您可以根据需要自定义修订表，以使用所需的信息扩展核心功能。 正如我上面提到的，一种这样的情况是与实体更改一起记录与应用会话关联的当前用户（在 Web 应用的情况下）。

为此，您需要一个自定义`@Entity`对象，该对象扩展了`org.hibernate.envers.DefaultRevisionEntity`并具有`@RevisionEntity`注解。 对于`@RevisionEntity`，如果要更新表中的数据，则必须添加自定义监听器类。 在此示例中，它将是用户名。 该监听器必须实现`org.hibernate.envers.RevisionListener`接口，如下所示。

```java
@Entity
 @RevisionEntity(AuditRevisionListener.class)
 public class AuditEntity extends DefaultRevisionEntity {

    private String username;
    // getters and setters
 }

public class AuditRevisionListener implements RevisionListener {

    @Override
    public void newRevision(Object revisionEntity) {

        final AuditEntity auditEntity = (AuditEntity) revisionEntity;
        // normally you would set here the name of the current user
        auditEntity.setUsername("GHajba");
    }
 }
```

## 在生产过程中切换审计表

您应该关心的一件事是在生产（甚至测试）期间切换审计表。 引入新表后，修订 ID（审计表中`REV`字段的内容）将立即重置并开始从 1 开始计数（如果您未指定其他任何要开始的序列）。 这意味着您必须知道何时切换以找到正确的修订信息，以找到正确的修订信息。

## 结论

如您所见，Hibernate 提供了一种很好的简便方法来对实体进行版本控制。 但是，我还是只是简单地探讨了各种可能性，但我希望我能给您一个好的起点。

## 代码下载

在此处下载 Hibernate [实体版本代码](https://github.com/JBTAdmin/Hibernate/tree/master/07_entity_versioning)。

