public override IAuditWorkUnit Dispatch(IWorkUnitMergeVisitor first) { if (first is PersistentCollectionChangeWorkUnit) { PersistentCollectionChangeWorkUnit original = (PersistentCollectionChangeWorkUnit)first; // Merging the collection changes in both work units. // First building a map from the ids of the collection-entry-entities from the "second" collection changes, // to the PCCD objects. That way, we will be later able to check if an "original" collection change // should be added, or if it is overshadowed by a new one. IDictionary <Object, PersistentCollectionChangeData> newChangesIdMap = new Dictionary <Object, PersistentCollectionChangeData>(); foreach (PersistentCollectionChangeData persistentCollectionChangeData in getCollectionChanges()) { newChangesIdMap.Add( getOriginalId(persistentCollectionChangeData), persistentCollectionChangeData); } // This will be the list with the resulting (merged) changes. List <PersistentCollectionChangeData> mergedChanges = new List <PersistentCollectionChangeData>(); // Including only those original changes, which are not overshadowed by new ones. foreach (PersistentCollectionChangeData originalCollectionChangeData in original.getCollectionChanges()) { if (!newChangesIdMap.ContainsKey(getOriginalId(originalCollectionChangeData))) { mergedChanges.Add(originalCollectionChangeData); } } // Finally adding all of the new changes to the end of the list mergedChanges = (List <PersistentCollectionChangeData>)mergedChanges.Concat(getCollectionChanges()); return(new PersistentCollectionChangeWorkUnit(sessionImplementor, EntityName, verCfg, EntityId, mergedChanges, ReferencingPropertyName)); } else { throw new Exception("Trying to merge a " + first + " with a PersitentCollectionChangeWorkUnit. " + "This is not really possible."); } }
private void OnCollectionAction(AbstractCollectionEvent evt, IPersistentCollection newColl, object oldColl, CollectionEntry collectionEntry) { if (!VerCfg.GlobalCfg.GenerateRevisionsForCollections) return; var entityName = evt.GetAffectedOwnerEntityName(); if (!VerCfg.EntCfg.IsVersioned(entityName)) return; var verSync = VerCfg.AuditProcessManager.Get(evt.Session); var ownerEntityName = ((AbstractCollectionPersister)collectionEntry.LoadedPersister).OwnerEntityName; var referencingPropertyName = collectionEntry.Role.Substring(ownerEntityName.Length + 1); // Checking if this is not a "fake" many-to-one bidirectional relation. The relation description may be // null in case of collections of non-entities. var rd = VerCfg.EntCfg[entityName].GetRelationDescription(referencingPropertyName); if (rd != null && rd.MappedByPropertyName != null) { GenerateFakeBidirecationalRelationWorkUnits(verSync, newColl, oldColl, entityName, referencingPropertyName, evt, rd); } else { var workUnit = new PersistentCollectionChangeWorkUnit(evt.Session, entityName, VerCfg, newColl, collectionEntry, oldColl, evt.AffectedOwnerIdOrNull, referencingPropertyName); verSync.AddWorkUnit(workUnit); if (workUnit.ContainsWork()) { // There are some changes: a revision needs also be generated for the collection owner verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, evt.GetAffectedOwnerEntityName(), VerCfg, evt.AffectedOwnerIdOrNull, evt.AffectedOwnerOrNull)); GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt, workUnit, rd); } } }
private void GenerateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess, IDatabaseEventArgs evt, PersistentCollectionChangeWorkUnit workUnit, RelationDescription rd) { // Checking if this is enabled in configuration ... if (!VerCfg.GlobalCfg.GenerateRevisionsForCollections) return; // Checking if this is not a bidirectional relation - then, a revision needs also be generated for // the other side of the relation. // relDesc can be null if this is a collection of simple values (not a relation). if (rd != null && rd.Bidirectional) { var relatedEntityName = rd.ToEntityName; var relatedIdMapper = VerCfg.EntCfg[relatedEntityName].IdMapper; foreach (var changeData in workUnit.CollectionChanges) { var relatedObj = changeData.GetChangedElement(); var relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj); auditProcess.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, evt.Session.BestGuessEntityName(relatedObj), VerCfg, relatedId, relatedObj)); } } }
private void GenerateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, AbstractCollectionEvent evt, PersistentCollectionChangeWorkUnit workUnit, RelationDescription rd) { // Checking if this is enabled in configuration ... if (!verCfg.GlobalCfg.isGenerateRevisionsForCollections()) { return; } // Checking if this is not a bidirectional relation - then, a revision needs also be generated for // the other side of the relation. // relDesc can be null if this is a collection of simple values (not a relation). if (rd != null && rd.Bidirectional) { String relatedEntityName = rd.ToEntityName; IIdMapper relatedIdMapper = verCfg.EntCfg[relatedEntityName].GetIdMapper(); foreach (PersistentCollectionChangeData changeData in workUnit.getCollectionChanges()) { Object relatedObj = changeData.GetChangedElement(); object relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj); verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, relatedEntityName, verCfg, relatedId, relatedObj)); } } }