【发布时间】:2018-06-06 17:07:42
【问题描述】:
我们有一个要求:使用 Hibernate Envers 根据差异记录和持久化事务中的实体更改。我们实现了RevisionListener:
public class MyRevisionListener implements EntityTrackingRevisionListener {
@Override
public void newRevision(Object revision) {
...
}
@Override
public void entityChanged(Class entityClass,
String entityName,
Serializable entityId,
RevisionType revisionType,
Object revisionEntity) {
int revisionId = ((DefaultRevisionEntity) revisionEntity).getId();
List<?> revisions = AuditReaderFactory.get(entityManager)
.createQuery()
.forRevisionsOfEntity(entityClass, false, true)
.add(AuditEntity.id().eq(entityId))
.add(AuditEntity.revisionNumber().le(revisionId + 1))
.addOrder(AuditEntity.revisionNumber().desc())
.setMaxResults(2)
.getResultList();
checkArgument(revisions.size() < 3, "Need at most two revisions: %s", revisions);
checkArgument(revisions.size() > 0, "Need at least one revision: %s", revisions);
// continue with diff calculation;
}
}
问题:
1. 第一个断言:我需要这个检查吗?有上述查询结果是否有可能包含两个以上的项目?
2. 第二个断言:我假设每次更改(INSERT/UPDATE/DELETE)至少有一个快照(或修订)。那正确吗?如果是这样,为什么我的测试用例(使用 UPDATE 操作)会因为断言失败(意味着没有快照)而随机失败。
如果我需要提供更多信息,请告诉我。
更新
问题在于 Spring 测试、上下文和 bean 管理(特别是我如何获得EntityManager)。我接受了@Naros 的帖子,因为它回答了第一个问题并回答了第二个问题:)
【问题讨论】:
-
是否有任何特殊原因您不能在查询时使用 AuditReader API 来执行此操作?我担心您可能会在并发场景中遇到问题,其中 2 个会话背靠背修改同一个条目,您最终可能会在事务提交时错误地生成差异。
-
查询时间是什么意思?我不知道该怎么做。有什么例子或指南吗?谢谢
-
让我问一下,您是否需要仅在 UI 中显示此 diff 或根据需要报告您可以访问 Envers API 的情况?我不想建议您打算直接从数据库访问它的解决方案。
-
我需要将差异作为事务的一部分进行持久化。
-
首先,Envers 允许您在
@Audited注释上使用withModifiedFlag=true选项来执行此操作。同样,我认为您不需要在此处编写任何自定义内容,而是在需要差异时使用 AuditReader API 来获取它。你没有给我任何真正可以继续下去的东西。
标签: hibernate hibernate-envers