首页 文章

Hibernate Envers - 包括发生更改的日期

提问于
浏览
3

我们刚刚开始使用Hibernate Envers,它适用于日志 what 已更改,但有没有一种方法可以记录 when 发生的变化?

那么,它可以在审计表中添加日期时间列吗?

根据Envers文档,这应该默认发生:

当Envers启动新版本时,它会创建一个新的修订实体,用于存储有关修订的信息 . 默认情况下,它仅包括修订号 - 整数值(int / Integer或long / Long) . 本质上是修订版本修订时间戳的主键 - 表示修订时刻的long / Long或java.util.Date值 . 使用java.util.Date而不是long / Long作为修订时间戳时,请注意不要将其存储到将丢失精度的列数据类型 .

因此,我的理解是,没有必要的操作来获取修订时间戳 . 但是,在我的情况下,envers创建的表中没有修订时间戳 .

谢谢

2 回答

  • 1

    您需要定义Envers使用的自定义RevisionEntity,以便添加所需的属性 . 有必要注释您假装用作自定义修订实体的类:

    @RevisionEntity(AuditingRevisionListener.class)

    在此实体中,您可以定义所需内容 . 例如,这应该是一个很好的起点:

    @Entity
    @Table(name = "DATA_REVIEW_TABLE")
    @RevisionEntity(AuditingRevisionListener.class)
    public class AuditedRevisionEntity {
      @RevisionNumber
      @Id
      @SequenceGenerator(name = "revisionSeq", sequenceName = "REVISION_DATOS_ID_SEQ", allocationSize = 1, initialValue = 1)
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "revisionSeq")
      private int id;
    
      @RevisionTimestamp
      private Date modifiedAt;
      private String username;
    
      public int getId() {
        return id;
      }
    
      public void setId(int id) {
        this.id = id;
      }
    
      public String getUsername() {
        return username;
      }
    
      public void setUsername(String username) {
        this.username = username;
      }
    
      @Temporal(value = TemporalType.TIMESTAMP)
      public Date getModifiedAt() {
        return modifiedAt;
      }
    
      public void setModifiedAt(Date modifiedAt) {
        this.modifiedAt = modifiedAt;
      }
    
    }
    

    此外,您还必须定义一个Revision listener来处理如何在自定义修订实体中初始化数据 . 您的侦听器必须实现RevisionListener .

    public class AuditingRevisionListener implements RevisionListener {
      private static Log log = LogFactory.getLog(AuditingRevisionListener.class.getName());
    
      @Override
      public void newRevision(Object revisionEntity) {
        AuditedRevisionEntity revEntity = (AuditedRevisionEntity) revisionEntity;
        String userName = null;
        try {
          if (SecurityContextHolder.getContext().getAuthentication() != null) {
            Object principal = getCurrentUserInfo();
            if (principal == null) {
              userName = "system";
            } else if (principal instanceof User) {
              userName = ((User) principal).getUsername();
            } 
          }
        } catch (Exception e) {
          log.error("Error auditing username.", e);
        }
        revEntity.setUsername(userName);
        revEntity.setModifiedAt(new Date());
      }
    }
    

    请记住,这些类必须可以通过hibernate访问,请检查:Why Hibernate Envers is ignoring my custom RevisionEntity?

  • 1

    有一个名为: REVINFO 的envers自动创建的表,其中包含时间戳 .

    它包含 REV 作为键,它是“ _AUD " table. This number is unique between all the " _AUD ”表中的修订号 .

    https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch15.html中的段落: 15.8. Understanding the Envers Schema

相关问题