Frage

Ich füge envers zu einer bestehenden Hibernate Entitäten. Alles funktioniert reibungslos bisher soweit Revision ist jedoch die Abfrage eine andere Frage, da die Revisionstabellen sind nicht mit den vorhandenen Daten gefüllt. Hat jemand dieses Problem bereits gelöst? Vielleicht haben Sie eine Möglichkeit, zu bevölkern die Revisionstabellen mit der vorhandenen Tabelle gefunden? Ich dachte, ich würde fragen, ich bin sicher, dass andere es nützlich finden würden.

War es hilfreich?

Lösung

Sie brauchen nicht zu.
AuditQuery ermöglicht es Ihnen, sowohl RevisionEntity und Datenrevision erhalten von:

AuditQuery query = getAuditReader().createQuery()
                .forRevisionsOfEntity(YourAuditedEntity.class, false, false);

Dies wird eine Abfrage erstellen, die eine Liste von Objekt zurück [3]. Fisrt Element ist Ihre Daten, die zweite ist die Revision Einheit und die dritte ist die Art der Revision.

Andere Tipps

Wir haben die ersten Daten bevölkert von einer Reihe von rohen SQL-Abfragen laufen zu simulieren „Einfügen“, um alle bestehenden Entitäten, als ob sie gerade zur gleichen Zeit erstellt worden war. Zum Beispiel:

insert into REVINFO(REV,REVTSTMP) values (1,1322687394907); 
-- this is the initial revision, with an arbitrary timestamp

insert into item_AUD(REV,REVTYPE,id,col1,col1) select 1,0,id,col1,col2 from item; 
-- this copies the relevant row data from the entity table to the audit table

beachten, dass der REVTYPE Wert 0 ein Insert, um anzuzeigen, (im Gegensatz zu einer Änderung gegenüber).

Sie werden ein Problem in dieser Kategorie haben, wenn Sie Envers ValidityAuditStrategy und haben Daten, die als mit Envers anderen erstellt wurde aktiviert.

In unserem Fall (Hibernate 4.2.8.Final) ein Basisobjekt Update wirft "Can not vorherige Revision für Unternehmen aktualisieren und" (angemeldet als [org.hibernate.AssertionFailure] HHH000099).

dauerte eine Weile, diese Diskussion / Erklärung so Cross-Posting zu finden:

ValidityAuditStrategy ohne Prüfsatz

Wir gelöst haben, das Problem zu bevölkern, die Prüfprotokolle mit den vorhandenen Daten wie folgt:

SessionFactory defaultSessionFactory;

// special configured sessionfactory with envers audit listener + an interceptor 
// which flags all properties as dirty, even if they are not.
SessionFactory replicationSessionFactory;

// Entities must be retrieved with a different session factory, otherwise the 
// auditing tables are not updated. ( this might be because I did something 
// wrong, I don't know, but I know it works if you do it as described above. Feel
// free to improve )

FooDao fooDao = new FooDao();
fooDao.setSessionFactory( defaultSessionFactory );
List<Foo> all = fooDao.findAll();

// cleanup and close connection for fooDao here.
..

// Obtain a session from the replicationSessionFactory here eg.
Session session = replicationSessionFactory.getCurrentSession();

// replicate all data, overwrite data if en entry for that id already exists
// the trick is to let both session factories point to the SAME database.
// By updating the data in the existing db, the audit listener gets triggered,
// and inserts your "initial" data in the audit tables.
for( Foo foo: all ) {
    session.replicate( foo, ReplicationMode.OVERWRITE ); 
}     

Die Konfiguration meines Datenquellen (via Frühling):

<bean id="replicationDataSource" 
      class="org.apache.commons.dbcp.BasicDataSource" 
      destroy-method="close">
  <property name="driverClassName" value="org.postgresql.Driver"/>
  <property name="url" value=".."/>
  <property name="username" value=".."/>
  <property name="password" value=".."/>
  <aop:scoped-proxy proxy-target-class="true"/>
</bean>

<bean id="auditEventListener" 
      class="org.hibernate.envers.event.AuditEventListener"/>

<bean id="replicationSessionFactory"
      class="o.s.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

  <property name="entityInterceptor">
    <bean class="com.foo.DirtyCheckByPassInterceptor"/>
  </property>

  <property name="dataSource" ref="replicationDataSource"/>
  <property name="packagesToScan">
    <list>
      <value>com.foo.**</value>
    </list>
  </property>

  <property name="hibernateProperties">
    <props>
      ..
      <prop key="org.hibernate.envers.audit_table_prefix">AUDIT_</prop>
      <prop key="org.hibernate.envers.audit_table_suffix"></prop>
    </props>
  </property>
  <property name="eventListeners">
    <map>
      <entry key="post-insert" value-ref="auditEventListener"/>
      <entry key="post-update" value-ref="auditEventListener"/>
      <entry key="post-delete" value-ref="auditEventListener"/>
      <entry key="pre-collection-update" value-ref="auditEventListener"/>
      <entry key="pre-collection-remove" value-ref="auditEventListener"/>
      <entry key="post-collection-recreate" value-ref="auditEventListener"/>
    </map>
  </property>
</bean>

Der Interceptor:

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
..

public class DirtyCheckByPassInterceptor extends EmptyInterceptor {

  public DirtyCheckByPassInterceptor() {
    super();
  }


  /**
   * Flags ALL properties as dirty, even if nothing has changed. 
   */
  @Override
  public int[] findDirty( Object entity,
                      Serializable id,
                      Object[] currentState,
                      Object[] previousState,
                      String[] propertyNames,
                      Type[] types ) {
    int[] result = new int[ propertyNames.length ];
    for ( int i = 0; i < propertyNames.length; i++ ) {
      result[ i ] = i;
    }
    return result;
  }
}

ps: bedenken Sie, dass dies ein vereinfachtes Beispiel ist. Es wird nicht der Box arbeiten, aber es wird Sie zu einer Arbeitslösung führen.

Hier finden Sie aktuelle http://www.jboss.org /files/envers/docs/index.html#revisionlog

Im Grunde können Sie Ihren eigenen ‚Revisionstyp‘ mit @RevisionEntity Anmerkung definieren, und dann einen RevisionListener Schnittstelle implementieren, um zusätzliche Audit-Daten einfügen, wie aktuelle Benutzer und hohe Betriebs. Normalerweise sind solche, gezogen von Threadkontext.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top