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

时间:2016-02-16 13:13:30

标签: java hibernate jpa hibernate-envers

我们刚刚开始使用Hibernate Envers,它适用于记录 更改的内容,但是,还有一种方法可以在发生更改时记录吗?

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

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

  

当Envers启动新版本时,它会创建一个新的修订实体,用于存储有关修订的信息。默认情况下,仅包括

     
      
  • 版本号 - 整数值(int / Integer或long / Long)。基本上是修订的主键
  •   
  • 修订时间戳 - 表示修订时刻的long / Long或java.util.Date值。当使用java.util.Date而不是long / Long作为修订时间戳时,请注意不要将它存储到松散精度的列数据类型。
  •   

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

由于

3 个答案:

答案 0 :(得分: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侦听器来处理在自定义修订实体中初始化数据的方式。您的监听器必须实现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 :(得分:1)

由名为 REVINFO 的envers自动创建一个包含时间戳的表。

它包含 REV 作为关键字,即“ _AUD ”表中的修订号。 此数字在所有“ _AUD ”表格中是唯一的。

见段落: 15.8。了解Envers架构  https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch15.html

答案 2 :(得分:0)

这对我有用:

select eaud.id, eaud.rev, eaud.revtype, eaud.curiigrp, eaud.startdate, eaud.enddate, to_char(

    TO_DATE('01/01/1970 00:00:00','DD/MM/YYYY HH24:MI:SS')

        + (rev.timestamp /1000/60/60/24 ||' day')::interval, 'YYYY/MM/DD'

) as hudate from mytable_aud eaud
join revisions rev on eaud.rev = rev.id