使用envers查找小于或等于给定修订的每个实体的最大修订版本

时间:2014-09-08 11:34:03

标签: hibernate hibernate-envers

这可能很简单,但无法找到方法。 我试图找到每个实体的最大修订数小于或等于给定的修订号。

AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(
    entityClass, false, false);
query.add(AuditEntity.revisionNumber().le(revisionNumber));     
query.addOrder(AuditEntity.revisionNumber().desc());
query.getResultList();

上面的代码按降序返回同一实体的多个修订版。我希望每个实体的最新版本小于或等于给定的版本号。

作为一种解决方法,我正在过滤resultSet,如下所示。我希望这个过滤可以在AuditQuery本身完成。

    AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(
            entityClass, false, false);
    query.add(AuditEntity.revisionNumber().le(revision));       
    query.addOrder(AuditEntity.revisionNumber().desc());
    List<?> list = query.getResultList();

    StringBuilder builder = new StringBuilder();
    EntityClass entity = null;
    Set<Long> entitySet = new HashSet<>();
    if (!list.isEmpty()) {
        for (int i = 0; i < list.size(); i++) {
            Object[] result = (Object[]) list.get(i);
            entity = (EntityClass) result[0];
            AuditRevision auditRevision = (AuditRevision) result[1];
            RevisionType operationType = (RevisionType) result[2];

            if (!entitySet.contains(entity.getId())) {
                //consider most recent revision of entity
                entitySet.add(entity.getId());
                builder.append(i + "-->");
                builder.append("id:" + entity.getId());
                builder.append(", auditRevision:" + auditRevision);
                builder.append(", operationType:" + operationType);
            }
        }
    }
    builder.append(", count:" + entitySet.size());

解决方案:

我们需要使用[https://hibernate.atlassian.net/browse/HHH-7827]的修正,即  AuditEntity.revisionNumber()。最大化()。computeAggregationInInstanceContext()。

    AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(
            entityClass, false, false);
    query.add(AuditEntity.revisionNumber().le(revision));
    query.add(AuditEntity.revisionNumber().maximize()
            .computeAggregationInInstanceContext());
    query.addOrder(AuditEntity.revisionNumber().desc());
    return query.getResultList();

2 个答案:

答案 0 :(得分:2)

我认为您正在寻找AuditEntitry.revisionNumber.max()约束。这应该最大化满足嵌套约束的修订号。

另请参阅documentation

答案 1 :(得分:0)

我一直在寻找类似的东西,但却找到了一种更好的方法来获得我想要的东西。今天花了一段时间来解决这个问题,但现在有意义了!

就我而言,我想在过去的特定日期获得实体。在Envers中,这意味着在特定版本中,因为修订在所有实体中是通用的,而不是每个实体。

因此,我们的想法是从日期中找到修订号,然后获取该修订版中的所有实体。我认为这与你所追求的类似。

AuditReader reader = AuditReaderFactory.get(this.entityManager);

Number latestRevAtDate = reader.getRevisionNumberForDate(convertedRunDate);

reader.createQuery()
      .forEntitiesAtRevision(MyEntity.class, latestRevAtDate)
      .add(AuditEntity.property("someEntityProperty").le("someValue"))
      .getResultList()

您只能使用各个实体,而不是每个实体的多个修订版,并且您在修订时获得系统中的所有实体。

这篇文章有点帮助: https://developer.jboss.org/message/625074#625074