How to retrieve the audited revision of relations?

后端 未结 2 1516
失恋的感觉
失恋的感觉 2020-12-20 03:54

Here is my use case

I have two entities : Personn and Email (a @OneToMany relation). Both of them are audited.

First I create a new Personn, with an Email (=

2条回答
  •  没有蜡笔的小新
    2020-12-20 04:40

    I tried to implement the second solution:

    1. First my integrator which adds a new post update listener (RevisionOnCollectionPostUpdateEventListenerImpl)

      public class RevisionOnCollectionUpdateIntegrator implements Integrator {
      private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, RevisionOnCollectionUpdateIntegrator.class.getName());
      
      public static final String REGISTER_ON_UPDATE = "org.hibernate.envers.revision_on_collection_update";
      
      @Override
      public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
      
          final boolean autoRegister = ConfigurationHelper.getBoolean(REGISTER_ON_UPDATE, configuration.getProperties(), true);
          if (!autoRegister) {
              LOG.debug("Skipping 'revision_on_collection_update' listener auto registration");
              return;
          }
      
          EventListenerRegistry listenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
          listenerRegistry.addDuplicationStrategy(EnversListenerDuplicationStrategy.INSTANCE);
      
          final AuditConfiguration enversConfiguration = AuditConfiguration.getFor(configuration, serviceRegistry.getService(ClassLoaderService.class));
          if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
              listenerRegistry.appendListeners(EventType.POST_UPDATE, new RevisionOnCollectionPostUpdateEventListenerImpl(enversConfiguration));
          }
      }
      
    2. And then the post update listener (which extends):

      public class RevisionOnCollectionPostUpdateEventListenerImpl extends EnversPostUpdateEventListenerImpl {
      protected final void generateBidirectionalWorkUnits(AuditProcess auditProcess, EntityPersister entityPersister, String entityName, Object[] newState,
              Object[] oldState, SessionImplementor session) {
          // Checking if this is enabled in configuration ...
          if (!getAuditConfiguration().getGlobalCfg().isGenerateRevisionsForCollections()) {
              return;
          }
      
          // Checks every property of the entity, if it is an "owned" to-one relation to another entity.
          // If the value of that property changed, and the relation is bi-directional, a new revision
          // for the related entity is generated.
          String[] propertyNames = entityPersister.getPropertyNames();
      
          for (int i = 0; i < propertyNames.length; i++) {
              String propertyName = propertyNames[i];
              RelationDescription relDesc = getAuditConfiguration().getEntCfg().getRelationDescription(entityName, propertyName);
              if (relDesc != null && relDesc.isBidirectional() && relDesc.getRelationType() == RelationType.TO_ONE && relDesc.isInsertable()) {
                  // Checking for changes
                  Object oldValue = oldState == null ? null : oldState[i];
                  Object newValue = newState == null ? null : newState[i];
      
                          // Here is the magic part !!!!!!!!!
                          // The super class verify if old and new value (of the owner value) are equals or not
                          // If different (add or delete) then an audit entry is also added for the owned entity
                          // When commented, an audit row for the owned entity is added when a related entity is updated
              //  if (!Tools.entitiesEqual(session, relDesc.getToEntityName(), oldValue, newValue)) {
                      // We have to generate changes both in the old collection (size decreses) and new collection
                      // (size increases).
                      if (newValue != null) {
                          addCollectionChangeWorkUnit(auditProcess, session, entityName, relDesc, newValue);
                      }
      
                      if (oldValue != null) {
                          addCollectionChangeWorkUnit(auditProcess, session, entityName, relDesc, oldValue);
                      }
              //  }
              }
          }
      }
      

    It seems to work but I have to test a little bit more.

提交回复
热议问题