2012-07-31 9 views
8

Estoy tratando de recuperar la última revisión de todas las entidades, que no se han eliminado. Hacer esto en SQL es muy simple con una subselección:Listado de la última revisión de cada entidad con envers

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

Pero no tengo ni idea, la forma de aplicar esto a través de la API envers. Empecé con AuditReader pero no encontró una manera, para seleccionar objetos distintos

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; 
} 

Importante: Quiero hacer esto en una o al menos dos consultas, porque tengo muchos artículos (entidades) con muchas revisiones

¡Muchas gracias!

Respuesta

7

Necesitamos utilizar la corrección de https://hibernate.atlassian.net/browse/HHH-7827, es decir, 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(); 

también se refieren a:

Find max revision of each entity less than or equal to given revision with envers

Can hibernate envers return the latest revision of all entities of a specific type?

+0

¿Hay forma de obtener el último número de revisión de una entidad? Digamos que se insertó una entidad, se actualizó dos veces y ahora tiene 3 números de revisión. ¿Cómo puedo obtener el último número de revisión? – AppSensei

+0

Hmm esto parece funcionar cuando tengo múltiples revisiones devueltas en la consulta, la función agregada me da la última (más alta) revisión. Pero si solo hay una revisión, no devuelve ninguna revisión. ¿Has tenido este problema? – chrismacp

+0

En realidad, creo que no entendí cómo estaba funcionando. Si filtra la última revisión de una entidad, esa entidad no se devuelve. Quería la última versión de la entidad después de filtrar las revisiones. Es decir. dame todas las revisiones antes del miércoles y dame la última versión de la entidad de ese subconjunto. No parece funcionar de esa manera. – chrismacp

0

esto funcionará:

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; 
    } 
    }); 

}

y luego

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; 
    } 
    }); 

}

+0

Gracias por su respuesta - Pero me gustaría encontrar la versión actualizada de todas las entidades y no para uno específico. No tengo una identificación para consultar – powerMicha

0

Trate de añadir una propiedad maximizado:

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

Esto me dará solo la revisión de la entidad más resentida. Necesito tener la última revisión de cada entidad que sale – powerMicha

+0

Hmm ¿lo intentó? Creo que debería generar una consulta con una subconsulta max() como en la pregunta. – adamw

+0

Sí, lo intenté. Y sí, genera una subconsulta con max(), pero la consulta secundaria no se evalúa por id, por lo que la consulta resultante se ve así: 'select * from article_aud aud1 donde rev in (seleccione max (rev) from article_aud aud2)' La comparación por id falta – powerMicha

Cuestiones relacionadas