Я использую 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;
I уже знаю точную ревизию! Как избежать этого подзапроса ?? Я просто хочу
select *
from persons_AUD person_aud0_
where person_aud0_.REV=462864
and person_aud0_.id=56591;
В настоящее время это вызывает серьезные проблемы с производительностью для больших таблиц.
Буду признателен за любой совет о том, как я могу убедить Envers использовать переданную ревизию как точное совпадение.