Search in sources :

Example 1 with DirtyTracker

use of com.blazebit.persistence.view.spi.type.DirtyTracker in project blaze-persistence by Blazebit.

the class ResetInitialStateSynchronization method afterCompletion.

@Override
@SuppressWarnings("unchecked")
public void afterCompletion(int status) {
    if (status != Status.STATUS_COMMITTED) {
        Map<EntityViewProxy, ViewTransition> objects;
        if (listenerManager.hasPostRollbackListeners()) {
            objects = new IdentityHashMap<>();
        } else {
            objects = null;
        }
        if (coalescedInitialStates != null) {
            for (int i = 0; i < coalescedInitialStates.size(); i += 2) {
                Object[] initialState = coalescedInitialStates.get(i);
                Object[] originalInitialState = coalescedInitialStates.get(i + 1);
                for (int j = 0; j < initialState.length; j++) {
                    initialState[j] = originalInitialState[j];
                }
            }
        }
        if (coalescedRecordingActions != null) {
            for (int i = 0; i < coalescedRecordingActions.size(); i += 4) {
                Object collectionReference = coalescedRecordingActions.get(i);
                Object actionList = coalescedRecordingActions.get(i + 1);
                Map<Object, Object> added = (Map<Object, Object>) coalescedRecordingActions.get(i + 2);
                Map<Object, Object> removed = (Map<Object, Object>) coalescedRecordingActions.get(i + 3);
                if (collectionReference instanceof RecordingCollection<?, ?>) {
                    RecordingCollection<Collection<Object>, Object> collection = (RecordingCollection<Collection<Object>, Object>) collectionReference;
                    collection.setActions((List<CollectionAction<Collection<Object>>>) (List<?>) actionList, added, removed);
                    collection.$$_markDirty(-1);
                } else {
                    Map<Object, Object> addedElements = (Map<Object, Object>) coalescedRecordingActions.get(i + 4);
                    Map<Object, Object> removedElements = (Map<Object, Object>) coalescedRecordingActions.get(i + 5);
                    RecordingMap<Map<Object, Object>, Object, Object> collection = (RecordingMap<Map<Object, Object>, Object, Object>) collectionReference;
                    collection.setActions((List<MapAction<Map<Object, Object>>>) (List<?>) actionList, added, removed, addedElements, removedElements);
                    collection.$$_markDirty(-1);
                    i += 2;
                }
            }
        }
        if (persistedViews != null) {
            for (int i = 0; i < persistedViews.size(); i += 7) {
                MutableStateTrackable view = (MutableStateTrackable) persistedViews.get(i);
                Object newObject = persistedViews.get(i + 1);
                view.$$_setIsNew(true);
                Object id = persistedViews.get(i + 2);
                DirtyTracker parent = (DirtyTracker) persistedViews.get(i + 3);
                int parentIndex = (int) persistedViews.get(i + 4);
                List<Object> readOnlyParents = (List<Object>) persistedViews.get(i + 5);
                if (id != NO_ID_MARKER) {
                    view.$$_setId(id);
                }
                if (parent != null) {
                    // This is not needed as this will happen when rolling back collection actions already
                    if (!(parent instanceof RecordingCollection<?, ?> || parent instanceof RecordingMap<?, ?, ?>)) {
                        parent.$$_replaceAttribute(newObject, parentIndex, view);
                    }
                    for (int j = 0; j < readOnlyParents.size(); j += 2) {
                        DirtyTracker readOnlyParent = (DirtyTracker) readOnlyParents.get(j);
                        int readOnlyParentIndex = (int) readOnlyParents.get(j + 1);
                        readOnlyParent.$$_replaceAttribute(newObject, readOnlyParentIndex, view);
                    }
                }
                view.$$_setDirty((long[]) persistedViews.get(i + 6));
                if (objects != null) {
                    objects.put(view, ViewTransition.PERSIST);
                }
            }
        }
        if (updatedViews != null) {
            for (int i = 0; i < updatedViews.size(); i += 2) {
                MutableStateTrackable view = (MutableStateTrackable) updatedViews.get(i);
                view.$$_setDirty((long[]) updatedViews.get(i + 1));
                if (objects != null) {
                    objects.put(view, ViewTransition.UPDATE);
                }
            }
        }
        if (removedViews != null) {
            for (int i = 0; i < removedViews.size(); i += 4) {
                EntityViewProxy view = (EntityViewProxy) removedViews.get(i);
                if (view instanceof MutableStateTrackable) {
                    MutableStateTrackable removedView = (MutableStateTrackable) view;
                    DirtyTracker parent = (DirtyTracker) removedViews.get(i + 1);
                    if (parent != null) {
                        removedView.$$_setParent(parent, (Integer) removedViews.get(i + 2));
                    }
                    long[] dirtyArray = (long[]) removedViews.get(i + 3);
                    if (dirtyArray != null) {
                        removedView.$$_setDirty(dirtyArray);
                    }
                }
                if (objects != null) {
                    objects.put(view, ViewTransition.REMOVE);
                }
            }
        }
        if (versionedViews != null) {
            for (int i = 0; i < versionedViews.size(); i += 2) {
                MutableStateTrackable view = (MutableStateTrackable) versionedViews.get(i);
                view.$$_setVersion(versionedViews.get(i + 1));
            }
        }
        if (objects != null) {
            PostRollbackInvoker postRollbackInvoker = new PostRollbackInvoker(updateContext, listenerManager, objects);
            TransactionSupport txSupport = updateContext.getEntityViewManager().getService(TransactionSupport.class);
            if (txSupport == null) {
                TransactionAccess transactionAccess = updateContext.getTransactionAccess();
                if (transactionAccess instanceof SynchronizationRegistry) {
                    transactionAccess = ((SynchronizationRegistry) transactionAccess).getTransactionAccess();
                }
                if (transactionAccess instanceof TransactionSupport) {
                    ((TransactionSupport) transactionAccess).transactional(postRollbackInvoker);
                } else {
                    // Log warning that querying doesn't work because we can't run in a new transaction?
                    postRollbackInvoker.run();
                }
            } else {
                txSupport.transactional(postRollbackInvoker);
            }
        }
    } else {
        if (listenerManager.hasPostCommitListeners()) {
            if (persistedViews != null) {
                for (int i = 0; i < persistedViews.size(); i += 7) {
                    listenerManager.invokePostCommit(updateContext, (MutableStateTrackable) persistedViews.get(i), ViewTransition.PERSIST);
                }
            }
            if (updatedViews != null) {
                for (int i = 0; i < updatedViews.size(); i += 2) {
                    listenerManager.invokePostCommit(updateContext, (MutableStateTrackable) updatedViews.get(i), ViewTransition.UPDATE);
                }
            }
            if (removedViews != null) {
                for (int i = 0; i < removedViews.size(); i += 4) {
                    listenerManager.invokePostCommit(updateContext, (EntityViewProxy) removedViews.get(i), ViewTransition.REMOVE);
                }
            }
        }
    }
}
Also used : MutableStateTrackable(com.blazebit.persistence.view.spi.type.MutableStateTrackable) ViewTransition(com.blazebit.persistence.view.ViewTransition) RecordingCollection(com.blazebit.persistence.view.impl.collection.RecordingCollection) TransactionSupport(com.blazebit.persistence.view.spi.TransactionSupport) EntityViewProxy(com.blazebit.persistence.view.spi.type.EntityViewProxy) ArrayList(java.util.ArrayList) List(java.util.List) DirtyTracker(com.blazebit.persistence.view.spi.type.DirtyTracker) RecordingMap(com.blazebit.persistence.view.impl.collection.RecordingMap) MapAction(com.blazebit.persistence.view.impl.collection.MapAction) SynchronizationRegistry(com.blazebit.persistence.view.impl.tx.SynchronizationRegistry) TransactionAccess(com.blazebit.persistence.view.spi.TransactionAccess) CollectionAction(com.blazebit.persistence.view.impl.collection.CollectionAction) RecordingCollection(com.blazebit.persistence.view.impl.collection.RecordingCollection) Collection(java.util.Collection) IdentityHashMap(java.util.IdentityHashMap) Map(java.util.Map) RecordingMap(com.blazebit.persistence.view.impl.collection.RecordingMap)

Example 2 with DirtyTracker

use of com.blazebit.persistence.view.spi.type.DirtyTracker in project blaze-persistence by Blazebit.

the class CompositeAttributeFlusher method flushEntity.

@Override
@SuppressWarnings("unchecked")
public boolean flushEntity(UpdateContext context, Object entity, Object ownerView, Object view, Object value, Runnable postReplaceListener) {
    if (element != null) {
        value = element;
    }
    if (!(value instanceof MutableStateTrackable)) {
        // Pass-through i.e. read-only id attributes
        for (int i = 0; i < flushers.length; i++) {
            DirtyAttributeFlusher<?, Object, Object> flusher = flushers[i];
            if (flusher != null) {
                flusher.flushEntity(context, entity, ownerView, value, flusher.getViewAttributeAccessor().getValue(value), null);
            }
        }
        return false;
    }
    MutableStateTrackable updatableProxy = (MutableStateTrackable) value;
    // The root object, which is given when view == value, is the exception
    if (context.isRemovedObject(updatableProxy) || !updatableProxy.$$_hasParent() && view != value) {
        return false;
    }
    final boolean shouldPersist = persist == Boolean.TRUE || persist == null && updatableProxy.$$_isNew();
    final boolean doPersist = shouldPersist && persistable;
    final Object oldId = determineOldId(context, updatableProxy, postReplaceListener);
    int parentIndex = updatableProxy.$$_getParentIndex();
    DirtyTracker parent = updatableProxy.$$_getParent();
    RecordingCollection<?, Object> recordingCollection = null;
    RecordingMap<?, Object, Object> recordingMap = null;
    Object removedValue = null;
    Set<Object> removedKeys = null;
    List<Integer> afterPersistFlushers = null;
    List<Integer> deferredFlushers = null;
    boolean successful = false;
    try {
        Object id = updatableProxy.$$_getId();
        if (doPersist) {
            // In case of nested attributes, the entity instance we get is the container of the attribute
            if (!entityClass.isInstance(entity)) {
                entity = entityLoader.toEntity(context, null, null);
            }
            context.invokePrePersist(updatableProxy, entity);
            // Or we are in the elementFlusher case where we don't iterate through the backing collection and thus can operate on the backing collection directly
            if (parent != null) {
                if (parent instanceof RecordingCollection<?, ?> && ((recordingCollection = (RecordingCollection<?, Object>) parent).isHashBased() || persistViewMapper != null)) {
                    if (recordingCollection.getCurrentIterator() == null) {
                        recordingCollection.getDelegate().remove(updatableProxy);
                    } else {
                        recordingCollection.getCurrentIterator().replace();
                    }
                } else if (parent instanceof RecordingMap<?, ?, ?> && (persistViewMapper != null || updatableProxy.$$_getParentIndex() == 1 && (recordingMap = (RecordingMap<?, Object, Object>) parent).isHashBased())) {
                    recordingMap = (RecordingMap<?, Object, Object>) parent;
                    // Parent index 1 in a recording map means it is part of the key
                    if (updatableProxy.$$_getParentIndex() == 1) {
                        if (recordingMap.getCurrentIterator() == null) {
                            removedValue = recordingMap.getDelegate().remove(updatableProxy);
                        } else {
                            removedValue = recordingMap.getCurrentIterator().replace();
                        }
                    } else {
                        if (removedKeys == null) {
                            removedKeys = new HashSet<>();
                        }
                        // Not sure if a creatable view should be allowed to occur multiple times in the map as value..
                        if (recordingMap.getCurrentIterator() == null) {
                            for (Map.Entry<Object, Object> entry : recordingMap.getDelegate().entrySet()) {
                                if (entry.getValue().equals(updatableProxy)) {
                                    removedKeys.add(entry.getKey());
                                }
                            }
                        } else {
                            recordingMap.getCurrentIterator().replaceValue(removedKeys);
                        }
                    }
                }
            }
            // A version 2.0 or 3.0 might improve on this when redesigning for operation queueing
            if (postReplaceListener != null) {
                postReplaceListener.run();
            }
            if (id != null) {
                idFlusher.flushEntity(context, entity, ownerView, updatableProxy, id, null);
            }
            context.getInitialStateResetter().addUpdatedView(updatableProxy);
        } else {
            // In case of nested attributes, the entity instance we get is the container of the attribute
            if ((loadForEntityFlush || viewIdAccessor == null) && !entityClass.isInstance(entity)) {
                entity = entityLoader.toEntity(context, view, id);
            }
            // After Pre-Update the dirtyness could change
            preUpdate(context, updatableProxy);
        }
        Object[] state = updatableProxy.$$_getMutableState();
        boolean wasDirty = false;
        boolean optimisticLock = false;
        if (updatableProxy instanceof DirtyStateTrackable) {
            Object[] initialState = ((DirtyStateTrackable) updatableProxy).$$_getInitialState();
            context.getInitialStateResetter().addState(initialState, initialState.clone());
            for (int i = 0; i < state.length; i++) {
                final DirtyAttributeFlusher<?, Object, Object> flusher = flushers[i];
                if (flusher != null) {
                    if (doPersist && flusher.requiresFlushAfterPersist(state[i])) {
                        if (afterPersistFlushers == null) {
                            afterPersistFlushers = new ArrayList<>();
                        }
                        afterPersistFlushers.add(i);
                        wasDirty = true;
                        optimisticLock |= flusher.isOptimisticLockProtected();
                    } else if (flusher.requiresDeferredFlush(state[i])) {
                        if (deferredFlushers == null) {
                            deferredFlushers = new ArrayList<>();
                        }
                        deferredFlushers.add(i);
                        wasDirty = true;
                        optimisticLock |= flusher.isOptimisticLockProtected();
                    } else {
                        Object newInitialValue = flusher.cloneDeep(value, initialState[i], state[i]);
                        if (flusher.flushEntity(context, entity, ownerView, value, state[i], null)) {
                            wasDirty = true;
                            optimisticLock |= flusher.isOptimisticLockProtected();
                        }
                        initialState[i] = flusher.getNewInitialValue(context, newInitialValue, state[i]);
                    }
                }
            }
        } else {
            for (int i = 0; i < state.length; i++) {
                final DirtyAttributeFlusher<?, Object, Object> flusher = flushers[i];
                if (flusher != null) {
                    if (doPersist && flusher.requiresFlushAfterPersist(state[i])) {
                        if (afterPersistFlushers == null) {
                            afterPersistFlushers = new ArrayList<>();
                        }
                        afterPersistFlushers.add(i);
                        wasDirty = true;
                        optimisticLock |= flusher.isOptimisticLockProtected();
                    } else if (flusher.requiresDeferredFlush(state[i])) {
                        if (deferredFlushers == null) {
                            deferredFlushers = new ArrayList<>();
                        }
                        deferredFlushers.add(i);
                        wasDirty = true;
                        optimisticLock |= flusher.isOptimisticLockProtected();
                    } else {
                        if (flusher.flushEntity(context, entity, ownerView, value, state[i], null)) {
                            wasDirty = true;
                            optimisticLock |= flusher.isOptimisticLockProtected();
                        }
                    }
                }
            }
        }
        // Pass through flushers
        for (int i = state.length; i < flushers.length; i++) {
            final DirtyAttributeFlusher<?, Object, Object> flusher = flushers[i];
            if (flusher != null) {
                if (flusher.flushEntity(context, entity, ownerView, value, flusher.getViewAttributeAccessor().getValue(value), null)) {
                    wasDirty = true;
                    optimisticLock |= flusher.isOptimisticLockProtected();
                }
            }
        }
        if (versionFlusher != null && optimisticLockProtected && optimisticLock) {
            context.getInitialStateResetter().addVersionedView(updatableProxy, updatableProxy.$$_getVersion());
            // We might have to load the entity for optimistic locking
            if (!entityClass.isInstance(entity)) {
                entity = entityLoader.toEntity(context, view, id);
            }
            versionFlusher.flushEntity(context, entity, ownerView, value, updatableProxy.$$_getVersion(), null);
        }
        if (deferredFlushers != null) {
            deferredFlushEntity(context, entity, ownerView, updatableProxy, deferredFlushers);
        }
        if (doPersist) {
            // If the class of the object is an entity, we persist the object
            context.getEntityManager().persist(entity);
            id = createViewIdByEntityId(entityLoader.getEntityId(context, entity));
            viewIdAccessor.setValue(updatableProxy, id);
        }
        successful = true;
        return wasDirty;
    } finally {
        int newObjectIndex = -1;
        if (shouldPersist) {
            if (idFlusher == null) {
                // Embeddables don't have an id
                newObjectIndex = context.getInitialStateResetter().addPersistedView(updatableProxy);
            } else {
                newObjectIndex = context.getInitialStateResetter().addPersistedView(updatableProxy, oldId);
            }
            if (successful && afterPersistFlushers != null) {
                deferredFlushEntity(context, entity, ownerView, updatableProxy, afterPersistFlushers);
            }
        } else if (successful && afterPersistFlushers != null) {
            deferredFlushEntity(context, entity, ownerView, updatableProxy, afterPersistFlushers);
        }
        Object newObject = null;
        if (doPersist) {
            newObject = updatableProxy;
            if (persistViewMapper != null) {
                newObject = persistViewMapper.map(newObject, context.getEntityViewManager().getOptionalParameters());
                context.getInitialStateResetter().addPersistedViewNewObject(newObjectIndex, newObject);
            }
            if (recordingCollection != null && (recordingCollection.isHashBased() || persistViewMapper != null)) {
                // Reset the parent accordingly
                resetParents(updatableProxy, parentIndex, parent, newObject);
                if (recordingCollection.getCurrentIterator() == null) {
                    recordingCollection.getDelegate().add(newObject);
                } else {
                    recordingCollection.getCurrentIterator().add(newObject);
                }
            } else if (recordingMap != null && (persistViewMapper != null || updatableProxy.$$_getParentIndex() == 1 && recordingMap.isHashBased())) {
                // Reset the parent accordingly
                resetParents(updatableProxy, parentIndex, parent, newObject);
                if (updatableProxy.$$_getParentIndex() == 1) {
                    if (recordingMap.getCurrentIterator() == null) {
                        recordingMap.getDelegate().put(newObject, removedValue);
                    } else {
                        recordingMap.getCurrentIterator().add(newObject, removedValue);
                    }
                } else {
                    for (Object removedKey : removedKeys) {
                        if (recordingMap.getCurrentIterator() == null) {
                            recordingMap.getDelegate().put(removedKey, newObject);
                        } else {
                            recordingMap.getCurrentIterator().add(removedKey, newObject);
                        }
                    }
                }
            } else if (parent != null && persistViewMapper != null) {
                // In case of a singular attribute, we replace the mutable state object to signal the parent flusher
                // SubviewAttributeFlusher is the parent, that uses this object for setting the actual and initial state
                ((MutableStateTrackable) parent).$$_getMutableState()[parentIndex] = newObject;
                updatableProxy.$$_unsetParent();
            }
            context.invokePostPersist(updatableProxy, entity);
        } else {
            context.invokePostUpdate(updatableProxy);
        }
    }
}
Also used : MutableStateTrackable(com.blazebit.persistence.view.spi.type.MutableStateTrackable) RecordingCollection(com.blazebit.persistence.view.impl.collection.RecordingCollection) ArrayList(java.util.ArrayList) DirtyStateTrackable(com.blazebit.persistence.view.spi.type.DirtyStateTrackable) DirtyTracker(com.blazebit.persistence.view.spi.type.DirtyTracker) BasicDirtyTracker(com.blazebit.persistence.view.spi.type.BasicDirtyTracker) RecordingMap(com.blazebit.persistence.view.impl.collection.RecordingMap) HashSet(java.util.HashSet)

Example 3 with DirtyTracker

use of com.blazebit.persistence.view.spi.type.DirtyTracker in project blaze-persistence by Blazebit.

the class DirtyStateViewAttributeAccessor method setValue.

@Override
public void setValue(Object view, Object value) {
    super.setValue(view, value);
    if (view instanceof MutableStateTrackable) {
        MutableStateTrackable mutableStateTrackable = (MutableStateTrackable) view;
        if (updatableOnly && value instanceof MutableStateTrackable) {
            ((MutableStateTrackable) value).$$_addReadOnlyParent(mutableStateTrackable, dirtyStateIndex);
        } else if (value instanceof DirtyTracker) {
            ((DirtyTracker) value).$$_setParent(mutableStateTrackable, dirtyStateIndex);
        }
        mutableStateTrackable.$$_getMutableState()[dirtyStateIndex] = value;
        if (view instanceof DirtyStateTrackable) {
            if (userType != null) {
                ((DirtyStateTrackable) view).$$_getInitialState()[dirtyStateIndex] = userType.deepClone(value);
            } else {
                ((DirtyStateTrackable) view).$$_getInitialState()[dirtyStateIndex] = value;
            }
        }
    }
}
Also used : MutableStateTrackable(com.blazebit.persistence.view.spi.type.MutableStateTrackable) DirtyStateTrackable(com.blazebit.persistence.view.spi.type.DirtyStateTrackable) DirtyTracker(com.blazebit.persistence.view.spi.type.DirtyTracker)

Example 4 with DirtyTracker

use of com.blazebit.persistence.view.spi.type.DirtyTracker in project blaze-persistence by Blazebit.

the class ViewMapper method map.

public T map(S source, Map<String, Object> optionalParameters) {
    Object[] tuple = new Object[objectMappers.length];
    for (int i = 0; i < objectMappers.length; i++) {
        if (objectMappers[i] != null) {
            tuple[i] = objectMappers[i].getValue(source, optionalParameters);
        }
    }
    T result = objectInstantiator.newInstance(tuple);
    boolean copiedInitialState = false;
    if (dirtyMapping != null && source instanceof DirtyTracker) {
        DirtyTracker oldDirtyTracker = (DirtyTracker) source;
        DirtyTracker dirtyTracker = (DirtyTracker) result;
        if (tryCopyInitialState && oldDirtyTracker instanceof DirtyStateTrackable && dirtyTracker instanceof DirtyStateTrackable) {
            Object[] oldInitial = ((DirtyStateTrackable) oldDirtyTracker).$$_getInitialState();
            Object[] newInitial = ((DirtyStateTrackable) dirtyTracker).$$_getInitialState();
            for (int i = 0; i < dirtyMapping.length; i++) {
                int dirtyStateIndex = dirtyMapping[i];
                if (oldDirtyTracker.$$_isDirty(dirtyStateIndex)) {
                    newInitial[i] = oldInitial[dirtyStateIndex];
                    dirtyTracker.$$_markDirty(i);
                }
            }
            copiedInitialState = true;
        } else {
            for (int i = 0; i < dirtyMapping.length; i++) {
                if (oldDirtyTracker.$$_isDirty(dirtyMapping[i])) {
                    dirtyTracker.$$_markDirty(i);
                }
            }
        }
    }
    boolean tryResetInitialState = false;
    if (source instanceof EntityViewProxy) {
        // CHECKSTYLE:OFF: FallThrough
        switch(entityViewKindMapping) {
            case MAP_REFERENCE_AND_NEW:
                if (((EntityViewProxy) source).$$_isNew()) {
                    ((MutableStateTrackable) result).$$_setIsNew(tryResetInitialState = true);
                }
            case MAP_REFERENCE:
                if (((EntityViewProxy) source).$$_isReference()) {
                    ((EntityViewProxy) result).$$_setIsReference(tryResetInitialState = true);
                }
                break;
            case MARK_NEW:
                ((MutableStateTrackable) result).$$_setIsNew(tryResetInitialState = true);
                break;
            default:
                throw new IllegalArgumentException("Unsupported entity view kind mapping: " + entityViewKindMapping);
        }
    // CHECKSTYLE:ON: FallThrough
    } else if (entityViewKindMapping == EntityViewKindMapping.MARK_NEW) {
        ((MutableStateTrackable) result).$$_setIsNew(tryResetInitialState = true);
    }
    if (!copiedInitialState && tryResetInitialState && result instanceof DirtyStateTrackable) {
        // Reset the initial state i.e. mark it as new
        Object[] initialState = ((DirtyStateTrackable) result).$$_getInitialState();
        Arrays.fill(initialState, null);
    }
    if (postConvert != null) {
        try {
            if (postConvertUsesSource) {
                postConvert.invoke(result, source);
            } else {
                postConvert.invoke(result);
            }
        } catch (Exception ex) {
            throw new RuntimeException("Error during invocation of post convert method!", ex);
        }
    }
    return result;
}
Also used : MutableStateTrackable(com.blazebit.persistence.view.spi.type.MutableStateTrackable) DirtyStateTrackable(com.blazebit.persistence.view.spi.type.DirtyStateTrackable) EntityViewProxy(com.blazebit.persistence.view.spi.type.EntityViewProxy) DirtyTracker(com.blazebit.persistence.view.spi.type.DirtyTracker)

Aggregations

DirtyTracker (com.blazebit.persistence.view.spi.type.DirtyTracker)4 MutableStateTrackable (com.blazebit.persistence.view.spi.type.MutableStateTrackable)4 DirtyStateTrackable (com.blazebit.persistence.view.spi.type.DirtyStateTrackable)3 RecordingCollection (com.blazebit.persistence.view.impl.collection.RecordingCollection)2 RecordingMap (com.blazebit.persistence.view.impl.collection.RecordingMap)2 EntityViewProxy (com.blazebit.persistence.view.spi.type.EntityViewProxy)2 ArrayList (java.util.ArrayList)2 ViewTransition (com.blazebit.persistence.view.ViewTransition)1 CollectionAction (com.blazebit.persistence.view.impl.collection.CollectionAction)1 MapAction (com.blazebit.persistence.view.impl.collection.MapAction)1 SynchronizationRegistry (com.blazebit.persistence.view.impl.tx.SynchronizationRegistry)1 TransactionAccess (com.blazebit.persistence.view.spi.TransactionAccess)1 TransactionSupport (com.blazebit.persistence.view.spi.TransactionSupport)1 BasicDirtyTracker (com.blazebit.persistence.view.spi.type.BasicDirtyTracker)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1 List (java.util.List)1 Map (java.util.Map)1