Frage

Ich habe eine Einheit geladen von Hibernate (via EntityManager):

User u = em.load(User.class, id)

Diese Klasse wird von Hibernate Envers geprüft. Wie kann ich die vorherige Version eines Benutzer Einheit laden?

War es hilfreich?

Lösung

vielleicht dann diese (von AuditReader docs)

AuditReader reader = AuditReaderFactory.get(entityManager);
User user_rev1 = reader.find(User.class, user.getId(), 1);

List<Number> revNumbers = reader.getRevisions(User.class, user_rev1);
User user_previous = reader.find(User.class, user_rev1.getId(),
  revNumbers.get(revNumbers.size()-1));

(Ich bin zu diesem sehr neu, nicht sicher, ob ich den ganzen Syntax Recht habe, vielleicht die Größe () - 1 sollte groß sein () - 2?)

Andere Tipps

Hier ist eine andere Version, die die vorherige Revision in Bezug auf eine „aktuelle“ Revisionsnummer findet, so kann es verwendet werden, selbst wenn das Objekt, das Sie bei gesuchte ist nicht die neueste Version. Es ist auch für den Fall, dass es nicht eine vorherige Überarbeitung. (em wird angenommen, dass ein zuvor bevölkerten EntityManager sein)

public static User getPreviousVersion(User user, int current_rev) {
    AuditReader reader = AuditReaderFactory.get(em);

    Number prior_revision = (Number) reader.createQuery()
    .forRevisionsOfEntity(User.class, false, true)
    .addProjection(AuditEntity.revisionNumber().max())
    .add(AuditEntity.id().eq(user.getId()))
    .add(AuditEntity.revisionNumber().lt(current_rev))
    .getSingleResult();

    if (prior_revision != null)
        return (User) reader.find(User.class, user.getId(), prior_revision);
    else
        return null
}

Dies kann zu verallgemeinern:

public static T getPreviousVersion(T entity, int current_rev) {
    AuditReader reader = AuditReaderFactory.get(JPA.em());

    Number prior_revision = (Number) reader.createQuery()
    .forRevisionsOfEntity(entity.getClass(), false, true)
    .addProjection(AuditEntity.revisionNumber().max())
    .add(AuditEntity.id().eq(((Model) entity).id))
    .add(AuditEntity.revisionNumber().lt(current_rev))
    .getSingleResult();

    if (prior_revision != null)
        return (T) reader.find(entity.getClass(), ((Model) entity).id, prior_revision);
    else
        return null
}

Das einzige knifflige Bit mit dieser Verallgemeinerung ist immer die Objekt-ID. Weil ich bin mit dem Spiel! Rahmen, ich kann die Tatsache ausnutzen, dass alle Unternehmen sind Modelle und verwenden ((Model) entity).id die ID zu bekommen, aber Sie werden diese anpassen müssen Ihre Umgebung anpassen.

Ich denke, es wäre dies:

final AuditReader reader = AuditReaderFactory.get( entityManagerOrSession );

// This could probably be declared as Long instead of Object
final Object pk = userCurrent.getId();

final List<Number> userRevisions = reader.getRevisions( User.class, pk );

final int revisionCount = userRevision.size();

final Number previousRevision = userRevisions.get( revisionCount - 2 );

final User userPrevious = reader.find( User.class, pk, previousRevision );

Aus der Dokumentation:

AuditReader reader = AuditReaderFactory.get(entityManager);
User user_rev1 = reader.find(User.class, user.getId(), 1);

Gebäude aus dem hervorragenden Ansatz von @ brad-Keule, ich habe folgende Änderungen vorgenommen:

  • Sie sollten statt Hardcoding in Ihrem entityClass und Id übergeben und das Modell unter der Annahme.
  • Sie Ihre EntityManager nicht hart codieren.
  • Es gibt keinen Punkt selectDeleted Einstellung, weil ein gelöschter Datensatz kann nie wie die vorherige Überarbeitung zurückgegeben werden.
  • Beim Einzelergebnis mit Wurf- und Ausnahme, wenn keine Ergebnisse oder mehr als 1 Ergebnis gefunden werden, also entweder rufen Ergebnisliste oder die Ausnahme abfangen (diese Lösung ruft getResultList mit maxResults = 1)
  • Holen Sie sich die Revision, Typen und Einheit in einer Transaktion (die Projektion entfernen, verwendet orderBy und maxResults und Abfrage für das Objekt [3])

hier ist also eine andere Lösung:

public static <T> T getPreviousRevision(EntityManager entityManager, Class<T> entityClass, Object entityId, int currentRev) {
    AuditReader reader = AuditReaderFactory.get(entityManager);
    List<Object[]> priorRevisions = (List<Object[]>) reader.createQuery()
            .forRevisionsOfEntity(entityClass, false, false)
            .add(AuditEntity.id().eq(entityId))
            .add(AuditEntity.revisionNumber().lt(currentRev))
            .addOrder(AuditEntity.revisionNumber().desc())
            .setMaxResults(1)
            .getResultList();

    if (priorRevisions.size() == 0) {
        return null;
    }
    // The list contains a single Object[] with entity, revinfo, and type 
    return (T) priorRevision.get(0)[0];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top