Frage

Ich bin derzeit mit Hibernate Envers arbeiten.

Wie Einträge in der Audit-Tabelle auf die Entität Ich mag mit Bezug zu löschen löschen? Mein Unternehmen hat keine Beziehung zu anderen Einheiten.

Ich fand heraus, dass ich das in onPostDelete tun Methode meiner benutzerdefinierten Zuhörer:

import org.hibernate.envers.event.AuditEventListener;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PreCollectionRemoveEvent;
import org.hibernate.event.PreCollectionUpdateEvent;

public class MyListener extends AuditEventListener {

  ...
  @Override
  public void onPostDelete(PostDeleteEvent arg0) {
    // TODO Auto-generated method stub
    super.onPostDelete(arg0);
  }
  ...

}

Ich habe die Dokumentation, Foren, viele Dinge zu lesen, aber ich kann es nicht herausgefunden. Vielleicht ist es nicht möglich, ich weiß es nicht.

Hat jemand jemals getan dies vor?

War es hilfreich?

Lösung

Ok, ich bin 50% getan mit diesem für diejenigen, die wissen wollen.

Durch die Schöpfer von Hibernate Envers, Adam Warski, ich zitiere:

"id" ist ein Hibernate-Schlüsselwort für die id ein Unternehmen, ist was auch immer die Namen; bei -abschlussprüfungsgesellschaften, ist die ID Verbund und „originalId“ genannt. Versuchen Sie:

"delete from full.package.name.User_AUD u where u.originalId.id = :userid" 

Aber jetzt möchte ich auch Einträge gerne Audit-Tabelle in meinem revinfo Tabelle Bezug zu löschen.

Wenn jemand eine Ahnung hat, lassen Sie es mich wissen.

Andere Tipps

Dies ist vollständig an mich zu arbeiten, und keine native Abfrage erforderlich

AuditQuery aq = auditReader.createQuery()
                   .forRevisionsOfEntity( ErpEmploye.class, true, false);       
 aq.add( AuditEntity.id().eq( employe.getCodeId() ) );
 aq.add( AuditEntity.relatedId("period").eq( erpPeriod.getCodeId() ) );
 List result =  aq.getResultList();//parameters must be added, this call is required
 if (result.size()>0){
    Query query = (Query) PrivateAccessor.invokePrivateMethod( aq, "buildQuery", new Object[0]);
    String queryString = (String) PrivateAccessor.getPrivateField( query, "queryString", true );
    PrivateAccessor.setPrivateField( query, "queryString", queryString.replace("select e__ from", "delete from"), true );
    getDAO().executeQuery(query);//transaction required             
}

Wenn Sie eine Revision von ID auszulöschen möchten, können Sie die envers Tabelle zugreifen, direkt über eine native Abfrage verwenden. Es gibt zwei Tabellen, die Verweise auf die Revision enthalten. Angenommen, Ihre Audit-Tabelle des herkömmlichen _AUD Suffix verwendet, können Sie die Entität Tabellennamen programmatisch finden.

Hier sind einige Auszüge in Kotlin geschrieben:

fun getAuditTableName(em: EntityManager, aClass: Class<*>): String {
    return getAuditTableName(em, aClass.name) + "_AUD"
}

fun getEntityTableName(em: EntityManager, aClass: Class<*>): String {
    val session = em.unwrap(Session::class.java) as Session
    val sessionFactory = session.sessionFactory
    val hibernateMetadata = sessionFactory.getClassMetadata(className)
    val persister = hibernateMetadata as AbstractEntityPersister
    return persister.tableName
}

Nun, da wir die Tabellennamen haben, können wir die Zeilen in den Tabellen entfernen. (Setzen Sie diese in Ihrem JPA Transaktionsblock, ersetzen Sie den Inhalt nach Bedarf, und stellen Sie die SQL für Ihren Provider). So gegeben MyEntityClass und myRevisionId, können wir so etwas tun:

    val em:EntityManager = getEntityManager()
    val auditTableName = getAuditTableName(MyEntityClass::class.java)

    em.createNativeQuery("delete from `$auditTableName` where REV=${myRevisionId}").executeUpdate()
    em.createNativeQuery("delete from REVINFO where REV=${myRevisionId}").executeUpdate()

Wenn Sie von einem anderen Parameter als der RevisionId, einfach Abfrage für die die revisionIds in der entity_AUD Tabelle löschen und löschen Sie anschließend die gefundenen Zeilen in der genannten Art und Weise.

Beachten Sie, dass ein RevisionId mit mehr als 1 Einheit verbunden sein können, und alle Einträge werden in dem vorherigen Verfahren entfernt werden. Um die Revision für eine einzelne Einheit zu löschen, müssen Sie die Objekt-ID und Schlüsselfeld Namen des Unternehmens (s).

Hier Code für dynamisch die Feldnamen bekommen:

fun getEntityKeyNames(em: EntityManager, entityClass: Class<*>): List<String> {
    val session = em.unwrap(Session::class.java) as Session
    val sessionFactory = session.sessionFactory
    val hibernateMetadata = sessionFactory.getClassMetadata(entityClass.name)
    val persister = hibernateMetadata as AbstractEntityPersister
    return persister.keyColumnNames.toList()
}

Audit-Einträge werden in der Regel nur dann hinzugefügt, nicht gelöscht, auch wenn die damit verbundene Einrichtung gelöscht wird, damit ich nicht denken , dass die Envers API unterstützen dafür.

Nun, wenn wirklich wollen Sie Einträge entfernen für gelöschte Einheiten (dies irgendwie Niederlagen der Zweck der Rechnungsprüfung) können Sie vielleicht diese Verzögerung ein bisschen und stattdessen Einträge zu entfernen, um Löschzeit, eine tägliche nativen Abfrage, zum Beispiel laufen alle Nacht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top