如果您想按ID清除修订版本,可以使用本地查询直接访问envers表。有2个包含对修订版本的引用的表。假设您的审计表使用传统的_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()
}
" order by. * "
, 那么这对我也有效。Order by 可能是在 Envers 的较新版本中添加的。 - Dario Seidl