2017-08-28 11 views
2

Hibernate Enversを使用して、Clientという名前のエンティティの変更を監査します。これで、現在の(削除されていない)クライアントエンティティを、作成タイムスタンプを含む永続性レイヤーからすべて読み込みたいと思います。 Hibernate Enversは必要なすべての情報を監査テーブルに格納します。私にとっては、必要なクエリをどのように実行するかは不明です。私が試したことは以下の通りであった: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

答えて

0

コードは近いですが、いくつかのエラーがあると思います。

作成タイムスタンプを取得するには、そのユースケースに対して別のクエリを使用し、それを他のクエリと結びつける必要があります。次のクエリは、エンティティ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 /タイムスタンプマップとから上記結婚のその単に問題。

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. 
} 
+0

お返事ありがとうございました。したがって、単一のクエリでこのタスクを実行することはできません。 – herbrst

+0

IDごとにタイムスタンプと最大リビジョン番号の値を取得するためにクエリを統合することはできますが、データフェッチはまだ別のものにする必要があります。 – Naros

関連する問題