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

HIbernate Envers: retrieve snapshots inserted in the same transaction

我们有一个要求:使用 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) 至少有一个快照(或修订)。那正确吗?如果是这样,为什么我的测试用例(带有更新操作)由于断言失败(意味着没有快照)而随机失败。

如果我需要提供更多信息,请告诉我。

更新
问题在于 Spring 测试、上下文和 bean 管理(特别是我如何获得 EntityManager)。我接受了@Naros 的post,因为它回答了第一个问题并回答了第二个问题:)

Do I need this checking? Having the above query Is it possible that the result contains more than two items?

不,setMaxResults(2)会保证查询returns最多只有2行;但是您需要处理查询 returns 小于 2.

的用例

I assume for every change (INSERT/UPDATE/DELETE) there's at least one snapshot (or revision). Is that right? If so why do my test cases (with an UPDATE operation) fail randomly due to this assertion failure (meaning there's no snapshot).

我不希望您的测试用例随机失败,除非您正在做不该做的事情。 Envers 的审计过程非常确定,所以我希望它始终如一地失败或成功。

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

没有看到你的测试用例,我只能推测大部分。如果您可以 post 您的测试用例和实体映射,我可以更深入地挖掘。