Question

Je travaille actuellement avec Hibernate Envers.

Comment supprimer des entrées dans la table d'audit lié à l'entité que je veux supprimer? Mon entité n'a pas de relation avec d'autres entités.

je me suis dit que je dois faire dans la méthode de onPostDelete de mon auditeur personnalisé:

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);
  }
  ...

}

J'ai lu la documentation, des forums, beaucoup de choses, mais je ne peux pas comprendre. Peut-être pas possible, je ne sais pas.

Quelqu'un at-il jamais fait cela auparavant?

Était-ce utile?

La solution

Ok je suis 50% fait avec cela pour ceux qui veulent savoir.

Merci au créateur d'Hibernate, Adam Envers Warski, je cite:

  

« id » est un mot-clé veille prolongée pour l'ID   d'une entité, quel que soit le nom est;   dans le cas des entités d'audit, l'id est   composite et est appelé « originalId ».   Essayez:

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

Mais maintenant, je voudrais également supprimer des entrées liées à la table d'audit dans ma table de revinfo.

Si quelqu'un a une idée, laissez-moi savoir.

Autres conseils

Cela fonctionne bien pour moi, et aucune requête native requise

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             
}

Si vous voulez effacer une révision par ID, vous pouvez accéder à la table directement à l'aide d'une Envers requête native. Il y a 2 tables qui contiennent des références à la révision. En supposant que votre table d'audit utilise le suffixe _AUD classique, vous pouvez trouver le nom de la table de l'entité programme.

Voici quelques extraits écrits dans Kotlin:

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
}

Maintenant que nous avons le nom de la table, on peut supprimer les lignes dans les tables. (Mettez dans votre bloc de transaction JPA, remplacer le contenu en fonction des besoins, et régler le SQL pour votre fournisseur). Donc, étant donné MyEntityClass et myRevisionId, nous pouvons faire quelque chose comme ceci:

    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()

Si vous voulez supprimer par un autre paramètre que la RevisionId, il suffit de requête pour les revisionIds les dans le tableau entity_AUD, puis supprimez les lignes trouvées de la manière indiquée.

Gardez à l'esprit qu'un RevisionId peut être associée à une entité plus de 1, et toutes les entrées seront supprimées dans la méthode précédente. Pour supprimer la révision d'une seule entité, vous aurez besoin d'un nom de domaine clé de l'identité et entité de l'entité (s).

Voici le code pour obtenir dynamiquement le nom du champ:

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()
}

entrées d'audit sont généralement ajoutés seulement, pas supprimé, même lorsque l'entité associée est supprimée, donc je ne suis pas penser que l'API fournissent un appui pour Envers cela.

Maintenant, si vraiment vous voulez supprimer les entrées pour les entités supprimées (ce défaites un peu le but de l'audit), vous pouvez peut-être retarder un peu et au lieu de supprimer des entrées au moment de la suppression, exécutez une requête native quotidienne, par exemple tous les nuit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top