【问题标题】:Find max revision of each entity less than or equal to given revision with envers使用 envers 查找小于或等于给定修订的每个实体的最大修订
【发布时间】:2014-11-01 14:49:15
【问题描述】:

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

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

以上代码按降序返回同一实体的多个修订版本。我想获得小于或等于给定版本号的每个实体的最新不同版本。

作为一种解决方法,我正在过滤结果集,如下所示。我希望这种过滤可以在 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().maximize().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();

【问题讨论】:

    标签: hibernate hibernate-envers


    【解决方案1】:

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

    另请参阅documentation 关于这件事。

    【讨论】:

    • 感谢您的回复。 revisionNumber.max() 没有帮助。我将编辑问题并进行更多解释。
    • 您可以使用max() 约束发布您的查询吗?我认为它应该有所帮助,它是为您的用例设计的 :)
    • 非常感谢,亚当!你的评论让我找到了更多。它只不过是 AuditEntity.revisionNumber().maximize().computeAggregationInInstanceContext() ([hibernate.atlassian.net/browse/HHH-7827])。
    【解决方案2】:

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

    就我而言,我想在过去的特定日期获取实体。在 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-04
      • 2017-11-28
      • 2012-02-20
      • 2013-05-24
      • 1970-01-01
      • 2019-08-20
      • 2021-04-06
      • 2020-03-09
      相关资源
      最近更新 更多