HIbernate Envers:检索在同一事务中插入的快照

时间:2018-06-04 15:31:39

标签: hibernate hibernate-envers

我们有一个要求:使用Hibernate Envers记录并在diff中保持事务中的实体更改。我们实施了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 Test,context和bean管理上(具体来说我是如何获得EntityManager)。我接受了@Naros的帖子,因为它回答了第一个问题,并对第二个问题进行了点击:)

1 个答案:

答案 0 :(得分:0)

  

我需要这个检查吗?有了上述查询结果是否可能包含两个以上的项目?

不,setMaxResults(2)将保证查询最多只返回2行;但是,您需要处理查询返回小于2的用例。

  

我假设每次更改(INSERT / UPDATE / DELETE)至少有一个快照(或修订版)。是对的吗?如果是这样的话,为什么我的测试用例(使用UPDATE操作)由于断言失败而意外失败(意味着没有快照)。

我不希望你的测试用例随机失败,除非你做的事情不应该做。使用Envers的审计过程非常具有确定性,因此我希望它能够失败或一直成功。

至于为什么你没有得到预期的行数,我的猜测是某些刷新模式配置正在发挥作用,可能会干扰Envers审计查询,或者你可能正在查询审计模式保存实体及其关联,使得期望的有效谓词where子句在该精确时刻无效?

在没有看到您的测试用例的情况下,我只能推测大部分内容。如果你可以发布你的测试用例和实体映射,我可以深入挖掘一下。