提问者:小点点

使用envers列出每个实体的最新版本


我正在尝试检索所有实体的最新版本,尚未删除。在SQL中执行此操作非常简单,只需一个子选择:

select * from article_aud aud1
where rev in
 (select max(rev) from article_aud aud2
  where aud1.id = aud2.id)
and revtype < 2

但是我不知道如何通过enversAPI实现这一点。我从AuditReader开始,但没有找到选择不同对象的方法

public List<Object[]> findLatestArticleRevisions(){
    List<Object[]> results = (List<Object[]>) getJpaTemplate().execute(new AuditReaderCallback() {
        @Override
        public Object doInAuditReader(AuditReader auditReader) {
            return auditReader.createQuery().forRevisionsOfEntity(Article.class, false, false)
                // TODO select distinct on entities
                .addOrder(new PropertyAuditOrder(new RevisionNumberPropertyName(), false))
                .getResultList();
        }
    });

    return results;
}

重要提示:我想在一个或至少两个查询中做到这一点,因为我有许多文章(实体)有许多修订。

非常感谢!


共3个答案

匿名用户

我们需要使用https://hibernate.atlassian.net/browse/HHH-7827的修复,即AuditEntityInInstanceNumber()。最大化(). 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();

还参考:

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

hibernate envers可以返回特定类型的所有实体的最新版本吗?

匿名用户

这将工作:

    public <T extends AbstractPersistentEntity> Number latestRevision(final Class<T> entityClass,
        final long uniqueIdentifier) {
  return hibernateTemplate.execute(new HibernateCallback<Number>() {
     @Override
     public Number doInHibernate(Session session) throws HibernateException, SQLException {
        try {
           Number number = (Number) get(session).createQuery()
                    .forRevisionsOfEntity(entityClass, true, true)
                    .addProjection(AuditEntity.revisionNumber().max())
                    .add(AuditEntity.id().eq(uniqueIdentifier)).getSingleResult();
           if (number != null) {
              logger.debug("max_rev = %s for entity_class %s.%s", number,
                       entityClass.getSimpleName(), uniqueIdentifier);
           }
           return number;
        } catch (javax.persistence.NoResultException e) {
           logger.debug(
                    "unable to find revision number by[entity_class=%s,unique_identifier=%s]",
                    entityClass.getName(), uniqueIdentifier);
        }
        return null;
     }
  });

}

然后

    protected <T extends AbstractPersistentEntity> T loadForRevision(final Class<T> entityClass,
        final long uniqueIdentifier, final Number revisionNumber) {
  return (T) hibernateTemplate.execute(new HibernateCallback<Object>() {
     @Override
     public Object doInHibernate(Session session) throws HibernateException, SQLException {
        T result = get(session).find(entityClass, uniqueIdentifier, revisionNumber);
        return result;
     }
  });

}

匿名用户

尝试添加最大化属性:

[your query].add(AuditEntity.revisionNumber().maximize())