You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用原生查询删除Hibernate Envers中3个月以上的审计历史

删除Hibernate Envers旧审计数据(非原生查询方式)

要清理距今3个月以上的审计数据且不使用原生SQL,核心思路是先定位过期的修订记录,再关联删除对应审计表数据,具体步骤如下:

1. 获取AuditReader实例

通过EntityManager获取Envers的AuditReader,用于查询修订信息:

AuditReader auditReader = AuditReaderFactory.get(entityManager);

2. 计算时间阈值

算出3个月前的毫秒级时间戳,作为筛选过期修订的条件:

LocalDate threeMonthsAgo = LocalDate.now().minusMonths(3);
Instant cutoffInstant = threeMonthsAgo.atStartOfDay(ZoneId.systemDefault()).toInstant();
long cutoffTimestamp = cutoffInstant.toEpochMilli();

3. 查询过期的修订ID

从默认的REVINFO表(对应实体DefaultRevisionEntity)中筛选出时间早于阈值的修订ID列表:

List<Number> oldRevIds = auditReader.createQuery()
    .forEntitiesAtRevision(DefaultRevisionEntity.class, Number.class)
    .add(AuditEntity.revisionProperty("timestamp").lt(cutoffTimestamp))
    .getResultList();

4. 删除审计表中的关联数据

针对每个实体的审计表(比如你提到的Entity_History),用JPQL删除关联这些过期修订ID的记录。必须先处理所有审计表,再删除REVINFO记录,避免外键约束报错:

// 示例:删除Entity_History表中的过期审计数据
String deleteAuditJpql = "DELETE FROM Entity_History e WHERE e.rev IN :oldRevIds";
entityManager.createQuery(deleteAuditJpql)
    .setParameter("oldRevIds", oldRevIds)
    .executeUpdate();

// 如有多个实体的审计表,重复上述操作即可

5. 删除REVINFO中的过期修订记录

最后清理REVINFO表中对应的旧记录:

String deleteRevJpql = "DELETE FROM DefaultRevisionEntity r WHERE r.id IN :oldRevIds";
entityManager.createQuery(deleteRevJpql)
    .setParameter("oldRevIds", oldRevIds)
    .executeUpdate();

注意事项

  • 所有操作需在同一个事务中执行,保证数据一致性。
  • 若审计表为自定义命名,需确保JPQL中使用的实体类名称与Envers生成的审计实体(或你自定义的审计实体类)对应。
  • 批量删除前建议备份数据,避免误删。

内容的提问来源于stack exchange,提问作者L. Tudy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:01:45