2012-07-31 12 views
8

Próbuję pobrać najnowszą wersję wszystkich encji, które nie zostały usunięte. Robi to w SQL jest bardzo prosta z podselekcji:Wyświetlanie najnowszej wersji każdej encji z envers

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

Ale nie mam pojęcia, jak zaimplementować to za pośrednictwem interfejsu API envers. Zacząłem AuditReader ale nie znaleźliśmy sposobu, aby wybrać różne obiekty

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

Ważne: Chcę to zrobić w jednym lub co najmniej dwóch zapytań, ponieważ mam wiele artykułów (podmioty) z wieloma rewizje.

Wielkie dzięki!

Odpowiedz

7

Musimy użyć poprawki z https://hibernate.atlassian.net/browse/HHH-7827, tj. 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(); 

Patrz także:

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

Czy istnieje sposób uzyskania najnowszej wersji jednostki? Powiedzmy, że encja została wstawiona, zaktualizowana dwukrotnie i teraz ma 3 numery wersji. Jak mogę uzyskać ostatni numer wersji? – AppSensei

+0

Hmm to wydaje się działać, gdy mam wiele wersji zwróconych w zapytaniu, funkcja agregująca daje mi najnowszą (najwyższą) wersję. Ale jeśli jest tylko jedna wersja, to w ogóle nie zwraca żadnej poprawki. Czy masz ten problem? – chrismacp

+0

Myślę, że źle zrozumiałem, jak to działa. Jeśli odfiltrować ostatnią rewizję jednostki, ta jednostka nie zostanie zwrócona. Chciałem najnowszą wersję encji po odfiltrowaniu wersji. To znaczy. daj mi wszystkie poprawki przed środą i daj mi najnowszą wersję podmiotu z tego podzbioru. Wygląda na to, że nie działa w ten sposób. – chrismacp

0

to będzie działać:

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

}

a następnie

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

Dzięki za odpowiedź - Ale chciałbym, aby znaleźć najnowszą wersję dla wszystkich podmiotów, a nie do jednego konkretnego. Nie mam identyfikatora do zapytania na – powerMicha

0

Spróbuj dodać zmaksymalizowane właściwość:

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

To da mi tylko rewizję większości ponownie zmienionych podmiotów. Muszę mieć najnowszą wersję każdego wychodzącego podmiotu – powerMicha

+0

Hmm, czy próbowałeś? Myślę, że powinno generować zapytanie z podzapytaniem max() jak w pytaniu. – adamw

+0

Tak, próbowałem. I tak, generuje podzapytanie z max(), ale sub-zapytanie nie jest oceniane na id, więc wynikowe zapytanie wygląda tak: 'select * from article_aud aud1 gdzie rev in (wybierz max (rev) z article_aud aud2)' Porównanie przez identyfikator brakuje – powerMicha