Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate Envers的“ForentiesAtrevision”生成冗余子查询_Hibernate_Hibernate Envers - Fatal编程技术网

Hibernate Envers的“ForentiesAtrevision”生成冗余子查询

Hibernate Envers的“ForentiesAtrevision”生成冗余子查询,hibernate,hibernate-envers,Hibernate,Hibernate Envers,我正在使用Hibernate Envers审核实体更改。实体和审计表存储在MySQL数据库中。这个解决方案在大多数情况下都很好,但我发现了一个非常奇怪的问题 假设我有一个特定修订的实体状态,我想得到该实体的先前更改。为此,我编写了以下方法: public <T> T getLastChange(@Nonnull Object id, @Nonnull Class<T> type, long beforeRev) { List<Number&g

我正在使用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);
    }
我已经知道确切的版本了!如何避免此子查询??我只是想

select *
from persons_AUD person_aud0_
where person_aud0_.REV=462864
  and person_aud0_.id=56591;
目前,它在大表上会导致严重的性能问题


如果您能就如何说服Envers使用通过的修订版作为精确匹配提供建议,我将不胜感激。

我找到了解决问题的方法。 AuditReader.find方法使用ForEntitysAtRevision,它始终生成该子查询。 但经过一些实验,我注意到另一种修改实体的方法可以完全满足我的要求。 因此,我将我的问题改写如下

    public <T> T getPreviousChange(@Nonnull Object id, @Nonnull Class<T> type, int beforeRev) {

        List resultList = getEntityManager().createQuery()
                .forRevisionsOfEntity(type, type.getName(), true, true)
                .add(AuditEntity.id().eq(id))
                .add(AuditEntity.revisionNumber().lt(beforeRev))
                .addOrder(AuditEntity.revisionNumber().desc())
                .setMaxResults(1).getResultList();

        return resultList.isEmpty() ? null : (T) resultList.get(0);
    }
现在,我得到的不是两个查询,而是一个:

select *
from persons_AUD person_aud0_ 
where person_aud0_.id=? and person_aud0_.REV<? 
order by person_aud0_.REV desc limit ?
即使在一张大桌子上,它的表现也相当不错

附言。 AuditQuery构造函数实际上非常丰富和强大! 以所需的方式修改查询很容易。 谢谢

select *
from persons_AUD person_aud0_ 
where person_aud0_.id=? and person_aud0_.REV<? 
order by person_aud0_.REV desc limit ?