如何判断Envers执行更新操作后是否生成审计记录?
判断Hibernate Envers是否生成审计记录以触发后续操作
不用手动对比对象字段,直接利用Envers自带的机制就能解决这个问题,给你两个可行方案:
方案1:通过版本号对比判断
Envers会在实体有变更时递增版本号,你可以借助这个特性判断:
- 先拿到更新前实体的原始版本号(数据库加载的实体带
@Version注解的字段值) - 执行保存后,用Envers的
AuditReader查询该实体的最新审计版本号 - 两个版本号不一样,就说明生成了审计记录,触发后续操作
代码示例:
// 先存下更新前的版本号 Integer originalVersion = student.getVersion(); Student savedStudent = repository.save(student); // 获取AuditReader实例 AuditReader auditReader = AuditReaderFactory.get(entityManager); // 查询当前实体的最新审计版本号 Number currentAuditVersion = auditReader.getRevisionNumberForEntity(student.getId(), Student.class); // 版本号变化则调用事件 if (!originalVersion.equals(currentAuditVersion)) { createQueueEvent("update", savedStudent); }
方案2:监听Envers的更新事件
注册一个Envers事件监听器,在监听器里标记是否生成了审计记录,业务代码里直接读这个标记:
- 写一个监听器实现
PostRevisionUpdateEventListener接口,用ThreadLocal存标记(避免线程干扰) - 触发审计记录时,监听器会把标记设为
true - 保存后检查标记,为
true就调用后续方法,记得用完清理标记
监听器实现
@Component public class EnversAuditListener implements PostRevisionUpdateEventListener { private static final ThreadLocal<Boolean> auditGeneratedFlag = new ThreadLocal<>(); @Override public void onPostRevisionUpdate(PostRevisionUpdateEvent event) { auditGeneratedFlag.set(true); } public static boolean isAuditRecordGenerated() { return Boolean.TRUE.equals(auditGeneratedFlag.get()); } public static void clearFlag() { auditGeneratedFlag.remove(); } }
业务代码中使用
// 先清空标记,避免残留值影响 EnversAuditListener.clearFlag(); Student savedStudent = repository.save(student); if (EnversAuditListener.isAuditRecordGenerated()) { createQueueEvent("update", savedStudent); } // 清理标记,防止线程污染 EnversAuditListener.clearFlag();
这两个方案都不用手动对比字段,完全依托Envers的原生机制,适配性更强。
内容的提问来源于stack exchange,提问作者R.Henderson
相关产品推荐
相关产品推荐

