2012-07-31 11 views
8

Sto cercando di recuperare l'ultima revisione di tutte le entità che non sono state eliminate. Fare questo in SQL è molto semplice con una subselect:Elenco dell'ultima revisione di ogni entità 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 

Ma non ho la più pallida idea, come implementare questo tramite l'API envers. Ho iniziato con AuditReader ma non ha trovato un modo, per selezionare oggetti distinti

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: io voglio fare questo in uno o almeno due interrogazioni, perché ho avuto molti articoli (entità) con molte revisioni.

Grazie mille!

risposta

7

È necessario utilizzare la correzione di https://hibernate.atlassian.net/browse/HHH-7827, ad esempio AuditEntity.revisionNumber(). Maxim(). 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(); 

si riferiscono anche 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

C'è modo di ottenere l'ultimo numero di revisione di un'entità? Dì come è stata inserita un'entità, aggiornata due volte e ora ha 3 numeri di revisione. Come posso ottenere l'ultimo numero di revisione? – AppSensei

+0

Hmm questo sembra funzionare quando ho più revisioni restituite nella query, la funzione di aggregazione mi dà l'ultima (la più alta) revisione. Ma se c'è una sola revisione, non restituisce alcuna revisione. Hai avuto questo problema? – chrismacp

+0

In realtà penso che abbia frainteso il modo in cui funzionava. Se si esclude l'ultima revisione di un'entità, tale entità non viene restituita. Volevo l'ultima versione dell'entità dopo aver filtrato le revisioni. Cioè dammi tutte le revisioni prima di mercoledì e dammi l'ultima versione dell'entità da quel sottoinsieme. Non sembra funzionare in questo modo. – chrismacp

0

questo funzionerà:

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

}

e poi

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

Grazie per la risposta - Ma mi piacerebbe trovare l'ultima revisione di tutte le entità e non per una specifica. Non ho un ID da interrogare per – powerMicha

0

Prova ad aggiungere una proprietà massimizzato:

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

Questo mi darà solo la revisione dell'entità modificata più risentita. Devo avere l'ultima revisione di ogni entità esistente – powerMicha

+0

Hmm hai provato? Penso che dovrebbe generare una query con una sottoquery max() come nella domanda. – adamw

+0

Sì, ho provato. E sì, genera una sottoquery con max(), ma la subquery non viene valutata per id in modo che la query risultante assomigli a questo 'select * from article_aud aud1 dove rev in (selezionare max (rev) da article_aud aud2)' Il confronto per ID mancante – powerMicha

Problemi correlati