【问题标题】:Hibernate Envers: How to get all current enties with their creation timestampsHibernate Envers:如何获取所有当前实体及其创建时间戳
【发布时间】:2017-08-28 08:30:56
【问题描述】:

我使用 Hibernate Envers 来审核名为 Client 的实体上的更改。现在我想从持久层读取所有当前(未删除)的客户端实体,包括它们的创建时间戳。 Hibernate Envers 将所有必要的信息存储在审计表中。对我来说,不清楚如何执行所需的查询。我尝试的是以下内容:

//Get last Revision Number for Entity Client
private Number getLastRev() {
    AuditReader auditReader = AuditReaderFactory.get(getEm());
    AuditQuery query = auditReader.createQuery()
            .forRevisionsOfEntity(Client.class, true, true)
            .addProjection(AuditEntity.revisionNumber().max());
    Number n = (Number) query.getSingleResult();
    return n;
}
public List<Object[]> getAllClientsWithCreationTimestamp() {
    Number revision = getLastRev();
    AuditReader auditReader = AuditReaderFactory.get(getEm());
    AuditQuery query = auditReader.createQuery()
            .forEntitiesAtRevision(Client.class, revision)
            .addProjection(AuditEntity.property("id"))
            .addProjection(AuditEntity.property("firstName"))
            .addProjection(AuditEntity.property("lastName"))
            .addProjection(AuditEntity.property("email"))                
            .addProjection(AuditEntity.revisionProperty("timestamp"))
            .addOrder(AuditEntity.revisionProperty("timestamp").desc());
}

不幸的是 getAllClientsWithCreationTimestamp() 列出了所有当前带有时间戳=“最后修改”不是“创建”时间戳的实体。

我希望任何人都可以帮助我创建正确的查询。

我的实体的 java 代码如下所示:

@Entity
@Table(name = "CLIENT")
@Audited
public class Client implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="CLIENT_SEQ")
@SequenceGenerator(name="CLIENT_SEQ", sequenceName="CLIENT_SEQ", allocationSize=1)
private Long Id;

@Column(name = "FIRST_NAME", length = 100)
private String firstName;

@Column(name = "LAST_NAME", nullable = false, length = 100)
private String lastName;

@Column(name = "EMAIL", nullable = false)
private String email;

public Long getId() {
    return Id;
}

public void setId(Long id) {
    Id = id;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}
}

我有以下数据库表:

  • REVISION:Envers 主修订实体表
  • CLIENT:存储客户端实体的表
  • CLIENT_AUD:用于存储客户端修订的表

database tables

【问题讨论】:

    标签: java hibernate jpa hibernate-envers


    【解决方案1】:

    您的代码很接近,但我相信您有一些错误。

    为了获得创建时间戳,您需要为该用例使用不同的查询,并将其与您的其他查询结合使用。以下查询将返回一个投影,其中包含实体 ID 以及创建审计行时的时间戳。您只需要使用它并创建一个 id/timestamp 对的映射。

    AuditQuery query = auditReader.createQuery()
      .forRevisionsOfEntity( Client.class, true, false )
      .addProjection( AuditEntity.id() )
      .addProjection( AuditEntity.revisionProperty( "timestamp" ) )
      .add( AuditEntity.revisionType().eq( RevisionType.ADD ) );
    

    接下来,您需要获取每个实体 id 的最新修订号,然后再次将结果转换为 id/修订号对的映射。

    AuditQuery query = auditReader.createQuery()
      .forRevisionsOfEntity( Client.class, true, false )
      .addProjection( AuditEntity.id() )
      .addProjection( AuditEntity.revisionNumber().max() );
    

    现在只需要求 Envers 根据最大​​修订号返回您的数据投影查询,并将其与上面的 id/timestamp 映射相结合。

    for ( Map.Entry<YourEntityIdType,Number> entry : idRevisionPairs.entrySet() ) {
      AuditQuery query = auditReader.createQuery()
        .forEntitiesAtRevision( Client.class, entry.getValue() )
        .add( AuditEntity.id().eq( entry.getKey() )
        .addProjection( ... );
    
      // here take the results from query and the id-timestamp pairs and
      // marry them into some DTO you return.
    }
    

    【讨论】:

    • 感谢您的回复纳罗斯。所以不可能在单个查询中执行此任务?
    • 您可以合并查询以获取每个 id 的时间戳和最大修订号值,但数据获取仍然需要分开我相信因为您感兴趣的数据不可能预计。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 2010-10-22
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多