Hibernate Envers:如何获取所有当前实体及其创建时间戳
Hibernate Envers: How to get all current enties with their creation timestamps
我使用 Hibernate Envers 来审核名为 Client 的实体的更改。现在我想从持久层读取所有当前(未删除)的客户端实体,包括它们的创建时间戳。 Hibernate Envers 将所有必要的信息存储在审计 table 中。对我来说,不清楚如何执行所需的查询。我尝试的是以下内容:
//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() 列出了时间戳 = "last modification" not "creation" 时间戳的所有当前实体。
我希望任何人都可以帮助我创建正确的查询。
我的实体的 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;
}
}
我有以下数据库 tables:
- REVISION:Envers 主要修订实体 table
- CLIENT:Table 存储 Client 实体
- CLIENT_AUD: Table 存储客户端修订
database tables
你的代码很接近,但我相信你有一些错误。
为了获得创建时间戳,您将需要针对该用例使用不同的查询并将其与其他查询结合起来。以下查询将为您提供 return 投影,其中包含创建审计行时的实体 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/revision-number 对的映射。
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.
}
我使用 Hibernate Envers 来审核名为 Client 的实体的更改。现在我想从持久层读取所有当前(未删除)的客户端实体,包括它们的创建时间戳。 Hibernate Envers 将所有必要的信息存储在审计 table 中。对我来说,不清楚如何执行所需的查询。我尝试的是以下内容:
//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() 列出了时间戳 = "last modification" not "creation" 时间戳的所有当前实体。
我希望任何人都可以帮助我创建正确的查询。
我的实体的 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;
}
}
我有以下数据库 tables:
- REVISION:Envers 主要修订实体 table
- CLIENT:Table 存储 Client 实体
- CLIENT_AUD: Table 存储客户端修订
database tables
你的代码很接近,但我相信你有一些错误。
为了获得创建时间戳,您将需要针对该用例使用不同的查询并将其与其他查询结合起来。以下查询将为您提供 return 投影,其中包含创建审计行时的实体 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/revision-number 对的映射。
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.
}