【发布时间】:2020-09-12 14:57:25
【问题描述】:
我正在使用 Hibernate Envers 来审计实体更改。实体和审计表存储在 MySQL 数据库中。该解决方案在大多数情况下都可以正常工作,但我发现了一个非常奇怪的问题。
假设我在某个版本中有一个实体状态,我想获取该实体的先前更改。为此,我编写了以下方法:
public <T> T getLastChange(@Nonnull Object id, @Nonnull Class<T> type, long beforeRev) {
List<Number> revisions = AuditReaderFactory.get(entityManager).getRevisions(type, id);
return revisions.stream()
.map(Number::longValue)
.filter(rev -> rev < beforeRev)
.max(Comparator.comparingLong(rev -> rev))
.map(rev -> AuditReaderFactory.get(entityManager).find(type, type.getName(), id, rev, true))
.orElse(null);
}
除了find 生成“太安全”的查询之外,它工作正常:
select *
from persons_AUD person_aud0_
where person_aud0_.REV=(select max(person_aud1_.REV) from persons_AUD person_aud1_ where person_aud1_.REV<=462864 and person_aud0_.id=person_aud1_.id)
and person_aud0_.id=56591;
我已经知道确切的版本了!如何避免这个子查询?我只是想要
select *
from persons_AUD person_aud0_
where person_aud0_.REV=462864
and person_aud0_.id=56591;
目前,它会导致大型表的性能问题。
对于如何说服 Envers 使用通过的修订版作为完全匹配的任何建议,我将不胜感激。
【问题讨论】:
标签: hibernate hibernate-envers