我目前正在使用Hibernate Envers。
如何在审计表中删除与要删除的实体相关的条目?我的实体与其他实体没有关系。
我想我必须在我的自定义侦听器的onPostDelete
方法中做到这一点:
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);
}
...
}
我已经阅读了文档,论坛,许多东西,但我不能弄明白。也许这是不可能的,我不知道。
以前有没有人这样做过?
发布于 2010-05-11 18:46:24
好了,对于那些想知道的人,我已经完成了50%。
感谢Hibernate Envers的创造者Adam Warski,我引用他的话:
" id“是代表实体id的hibernate关键字,无论名称是什么;对于审计实体,id是复合的,称为"originalId”。尝试:
"delete from full.package.name.User_AUD u where u.originalId.id = :userid"
但现在,我也想删除我的revinfo表中与audit表相关的条目。
如果有人有线索,请告诉我。
发布于 2014-04-20 15:20:11
这对我来说是完全有效的,并且不需要原生查询
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
}
发布于 2017-11-01 02:05:36
如果想要通过ID清除修订,可以使用原生查询直接访问envers表。有两个表包含对修订的引用。假设您的audit表使用传统的_AUD后缀,那么您可以通过编程方式找到实体表名。
以下是用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
}
现在我们有了表名,我们可以删除表中的行。(将其放入JPA事务块中,根据需要替换内容,并为您的提供者调整SQL )。在给定MyEntityClass和myRevisionId的情况下,我们可以这样做:
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()
如果您想通过revisionID以外的参数删除,只需在entity_AUD表中查询revisionIds,然后按上述方式删除找到的行即可。
请记住,一个revisionId可能与多个实体相关联,并且在前面的方法中将删除所有条目。要删除单个实体的修订,您需要该实体的ID和实体的键字段名。
下面是动态获取字段名的代码:
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()
}
https://stackoverflow.com/questions/2791148
复制