Class DataContextImpl
- All Implemented Interfaces:
DataContext,DataContextChanges,DataContextInternal
DataContext which saves data to DataManager.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classprotected classNested classes/interfaces inherited from interface io.jmix.flowui.model.DataContext
DataContext.ChangeEvent, DataContext.PostSaveEvent, DataContext.PreSaveEvent -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected DataContextChangeTrackerprotected Copierprotected DataManagerprotected Map<Object, Map<String, DataContextImpl.EmbeddedPropertyChangeListener>> protected EntityReferencesNormalizerprotected EntityStatesprotected EntitySystemStateSupportprotected EventHubprotected intprotected Metadataprotected MetadataToolsprotected @Nullable Objectprotected DataContextInternalprotected DataContextImpl.PropertyChangeListenerprotected ReferenceValuesSupportprotected Function<SaveContext, Set<Object>> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaddChangeListener(Consumer<DataContext.ChangeEvent> listener) Adds a listener toDataContext.ChangeEvent.addPostSaveListener(Consumer<DataContext.PostSaveEvent> listener) Adds a listener toDataContext.PostSaveEvent.addPreSaveListener(Consumer<DataContext.PreSaveEvent> listener) Adds a listener toDataContext.PreSaveEvent.protected booleanbeginMergeCollection(Object managedEntity, String propertyName) Marks the given owner entity's collection property as being merged within the active merge() call.protected voidcleanupContextAfterRemoveEntity(DataContextInternal context, Object removedEntity) voidclear()Evicts all tracked entities.voidClears the lists of modified and removed entities.protected voidcollectionChanged(Object entity, @Nullable String property) Mutation callback for the observable collection wrappers.booleanReturns true if the context contains the given entity (distinguished by its class and id).protected ObjectcopyEntity(Object srcEntity) protected voidcopySystemState(Object srcEntity, Object dstEntity) <T> TCreates an entity instance and merges it into the context.createObservableList(Object notifiedEntity, @Nullable String property) createObservableList(List<Object> list, Object notifiedEntity, @Nullable String property) createObservableSet(Object notifiedEntity, @Nullable String property) protected ObservableSet<Object> createObservableSet(Set<Object> set, Object notifiedEntity, @Nullable String property) protected voidendMergeCollection(Object managedEntity, String propertyName) Clears the in-progress marker set bybeginMergeCollection(java.lang.Object, java.lang.String)for the owner's collection property, once its merge finishes.protected voidentityBecameClean(Object entity) Change-tracker callback: an entity lost its last dirty attribute, so it leavesmodifiedInstancesunless it was pinned modified viasetModified(java.lang.Object, boolean)(manuallyModified).protected voidentityBecameDirty(Object entity) Change-tracker callback: an entity gained its first dirty attribute, so it joinsmodifiedInstances.protected booleanentityHasReference(Object entity, Object refEntity) voidRemoves the entity from the context so the context stops tracking it.voidClears the lists of created/modified/deleted entities and evicts these entities.filterSavedInstances(Set<Object> instances) <T> @Nullable TReturns an entity instance by its class and id.<T> @Nullable Tfind(T entity) Returns the instance of entity with the same id if it exists in this context.protected @Nullable ObjectfindCompositionOwner(Object entity) Resolves the composition owner of a managed instance in this context.protected voidfireChangeListener(Object entity) protected voidFires a singleChangeEventfor each entity queued indeferredChangeEntitiesduring a merge, then clears the queue.Collection<?> getAll()getDirtyEmbeddedPaths(Object dstEntity, String propertyName) Dotted attribute paths ('address.city') of the given embedded property that are dirty on the owning managed instance.protected MetaClassgetEntityMetaClass(Object entity) Returns an immutable set of entities registered as modified.getModifiedAttributes(Object entity) Returns the names of attributes of the given managed entity that were modified by the user and not yet saved.@Nullable DataContextReturns a parent context, if any.protected @Nullable StringgetPrimaryKeyPropertyName(Object entity) Returns an immutable set of entities registered for removal.Returns a function which will be used to save data instead of standard implementation.booleanReturns true if the context has detected changes in the tracked entities.protected ObjectinternalMerge(Object entity, Map<Object, Object> mergedMap, boolean isRoot, MergeOptions options) protected booleanisColdResetTarget(Object dstEntity, boolean isRoot, MergeOptions options, boolean dstExisted) Whether this is a root non-fresh or a fresh merge onto a pre-existing managed instance whose loaded-state info is the caching kind.protected booleanisEmbeddedToInstall(Object srcEntity, Object dstEntity, MetaProperty property, boolean isRoot, MergeOptions options) Whether a loaded embedded value must be installed on a destination that does not report it loaded: the destination is a reference, or the source is a reference in a root or fresh merge.protected booleanisMergeApplied(Object entity, String attribute) Whether the merge itself wrote the given (entity, attribute) during the active merge (seerecordMergeApplied(java.lang.Object, java.lang.String)).booleanisModified(Object entity) Returns true if the context has detected changes in the given entity.protected booleanisOverriding(String propertyName) Whether the dirty-protection of the given property of the merge root is suspended by the currentmergeFromChild(Object, Set)call.protected booleanisOverridingApplied(Object dstEntity, String propertyName, boolean isRoot) Whether the given property of the given instance was already written from the child by the root visit of the activemergeFromChild(Object, Set)call, so this later visit must not write it again.protected booleanisReferenceSource(Object srcEntity) Whether the source is a reference returned byDataManager.getReference()or a copy of one.protected booleanisReferenceTarget(Object dstEntity, boolean dstExisted) Whether the destination is a pre-existing reference.booleanReturns true if the context has registered removal of the given entity.protected Objectprotected voidmarkCompositionOwnersModified(Object entity) Marks the composition owner chain of a just-merged composition child for reopen protection in this (parent) context.protected voidmarkLoaded(Object entity, String propertyName) Marks an attribute as loaded on the entity's loaded-state info, soisLoadedreflects a value that is present in memory because it was set (a user edit) or installed by a merge, rather than lazily materialized.merge(Collection<?> entities) Merge the given entities into the context.merge(Collection<?> entities, MergeOptions options) Merge the given entities into the context.<T> Tmerge(T entity) Same asDataContext.merge(Object, MergeOptions)with default options.<T> Tmerge(T entity, MergeOptions options) Merge the given entity into the context.Merges an entity owning a composition child that a child context saved into this (parent) context.protected voidmergeDatatypeProperties(Object srcEntity, Object dstEntity, MetaClass metaClass, boolean srcNew, boolean dstNew, boolean isRoot, MergeOptions options) Copies the loaded datatype and element-collection properties from the source to the destination instance, honouring the dirty-aware merge rule (a destination attribute with an unsaved user edit is never overwritten; a fresh merge rebaselines it instead).protected ObjectmergeDirtyFromChild(Object entity, Set<String> childDirtyAttributes) Body ofmergeFromChild(Object, Set)for a non-empty set of child dirty attributes.mergeFromChild(Object entity, Set<String> childDirtyAttributes) Merges an entity saved by a child context into this (parent) context.protected voidmergeLazyLoadingState(Object srcEntity, Object dstEntity) protected voidmergeList(List<Object> list, Object managedEntity, MetaProperty property, boolean replace, MergeOptions options, Map<Object, Object> mergedMap) protected voidmergeLoadedPropertiesInfo(Object srcEntity, Object dstEntity, boolean isRoot, MergeOptions options, boolean coldReset) protected voidmergeReferenceProperties(Object srcEntity, Object dstEntity, MetaClass metaClass, boolean srcNew, boolean isRoot, MergeOptions options, Map<Object, Object> mergedMap) Copies the loaded reference and to-many properties from the source to the destination instance, recursively merging each reached node into the context graph.protected EntitySetmergeSaved(Set<Object> saved) protected voidmergeSet(Set<Object> set, Object managedEntity, MetaProperty property, boolean replace, MergeOptions options, Map<Object, Object> mergedMap) protected voidmergeState(Object srcEntity, Object dstEntity, Map<Object, Object> mergedMap, boolean isRoot, MergeOptions options, boolean dstExisted) protected voidmergeSystemState(Object srcEntity, Object dstEntity, boolean isRoot, MergeOptions options) protected voidmergeUnloadedOrNullReference(Object dstEntity, MetaProperty property, @Nullable Object value, Map<Object, Object> mergedMap, MergeOptions options) Installs a reference/to-many value when the source side is loaded but the destination side is not yet loaded (or the incoming value is null).performSave(boolean reloadSaved) protected StringprintEntity(Object entity, int level, Set<Object> visited) protected StringprintObject(Object object) protected voidMerges the composition owner chain of a modified instance into the parent context, so the parent's owner instances reference the propagated child.protected voidreapplySetLoaded(Object dstEntity) Re-asserts the set-loaded markers of an entity into its currentLoadedPropertiesInfo, so a value present in memory because it was set or merge-installed keeps reporting loaded after a fresh merge replaces the loaded-state cache with a narrower source's (seemergeLoadedPropertiesInfo(java.lang.Object, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions, boolean)).protected voidrebaselineEmbedded(Object dstEntity, String propertyName, @Nullable Object incomingEmbedded, Set<String> dirtyEmbeddedPaths) Fresh-merge rebaselining for an embedded property whose copy was skipped because the owner carries dirty state for it: the embedded reference entry itself (if dirty) and each dirty dotted sub-attribute path, using the sub-attribute values of the incoming (unmanaged) embedded instance.protected voidrecordMergeApplied(Object entity, String attribute) Records that the merge itself wrote the given (entity, attribute) during the active merge.protected voidremeasureAgainstBaseline(Object entity, String attribute) Re-measures an attribute that was already dirty in this context beforemergeFromChild(java.lang.Object, java.util.Set<java.lang.String>)wrote the child's value onto the managed instance: the attribute keeps this context's own baseline, and the value coming from the child can have returned it to that baseline, which un-dirties it.voidRemoves the entity from the context and registers it as deleted.protected voidremoveFromCollections(Object entityToRemove) protected voidremoveListeners(Object entity) protected voidresetLoadedInfoBeforeCopy(Object dstEntity, boolean coldReset) Blanks the destination's caching loaded-state info before the copy loops whencoldResetis set (seeisColdResetTarget(java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions, boolean)), so theirisLoadedchecks recompute from the fetch group just unioned inmergeSystemState(java.lang.Object, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions)rather than from a stale cached negative.protected static StringrootSegment(String attribute) The first segment of a possibly-dotted attribute path:'address'for'address.city', or the whole string when it has no dot.save()Saves changed and removed instances using DataManager or a custom save delegate.save(boolean reloadSaved) Saves changed and removed instances using DataManager, custom save delegate or merges them to parent data context if it is set.saveToDataManager(boolean reloadSaved) voidsetModified(Object entity, boolean modified) Registers or unregisters the given entity as modified.voidsetParent(DataContext parentContext) Sets the parent context.protected voidsetPropertyValue(Object entity, MetaProperty property, @Nullable Object value) protected voidsetPropertyValue(Object entity, MetaProperty property, @Nullable Object value, boolean checkEquals) voidsetSaveDelegate(Function<SaveContext, Set<Object>> delegate) Sets a function which will be used to save data instead of standard implementation.protected booleanskipOrRebaselineDirtyReference(Object dstEntity, MetaProperty property, @Nullable Object value, boolean isRoot, MergeOptions options, Map<Object, Object> mergedMap) Applies the dirty-aware merge rule to a reference or to-many property: when the destination attribute carries an unsaved user edit (including a dirty dotted path under an embedded reference), the incoming value is not installed.protected voidupdateFetchPlans(SaveContext saveContext) protected @Nullable ObjectvalueForBaseline(Object entity, String attribute) Baseline-shaped current value of the given attribute of a managed instance, in the formDataContextChangeTrackercompares against: a scalar value as is, a reference as its id, a to-many attribute as the membership bag of its current contents, a dotted path viaEntityValues.getValueEx(Object, String).protected Collection<Object> wrapLazyValueIntoObservableCollection(Collection<Object> collection, Object notifiedEntity, @Nullable String property) Wraps a collection in an observable list/set that notifiescollectionChanged(java.lang.Object, java.lang.String)on mutation and, when a property is given, snapshots the tracker baseline so a later mutation marks the owner modified.protected Collection<Object> wrapLazyValueIntoObservableCollection(Collection<Object> collection, Object notifiedEntity, @Nullable String property, boolean snapshotBaseline) Same aswrapLazyValueIntoObservableCollection(Collection, Object, String), with control over the baseline snapshot.
-
Field Details
-
metadata
-
metadataTools
-
entityStates
-
dataManager
-
entitySystemStateSupport
-
referenceValuesSupport
-
entityReferencesNormalizer
-
copier
-
events
-
-
modifiedInstances
-
removedInstances
-
changeTracker
-
manuallyModified
-
compositionModifiedOwners
-
overridingAttributes
-
overridingRoot
-
mergeCollectionInProgress
-
propertyChangeListener
-
mergeDepth
protected int mergeDepth -
deferredChangeEntities
-
mergeApplied
-
parentContext
-
saveDelegate
-
embeddedPropertyListeners
protected Map<Object,Map<String, embeddedPropertyListenersDataContextImpl.EmbeddedPropertyChangeListener>> -
nullIdEntitiesMap
-
-
Constructor Details
-
DataContextImpl
public DataContextImpl()
-
-
Method Details
-
getParent
Description copied from interface:DataContextReturns a parent context, if any. If the parent context is set,DataContext.save()method merges the changed instances to it instead of sending them to DataManager or a custom save delegate.- Specified by:
getParentin interfaceDataContext
-
setParent
Description copied from interface:DataContextSets the parent context. If the parent context is set,DataContext.save()andDataContext.save(boolean)methods merge the changed instances to it instead of sending them to DataManager or a custom save delegate.- Specified by:
setParentin interfaceDataContext
-
addChangeListener
Description copied from interface:DataContextAdds a listener toDataContext.ChangeEvent.- Specified by:
addChangeListenerin interfaceDataContext
-
fireChangeListener
-
flushDeferredChangeEvents
protected void flushDeferredChangeEvents()Fires a singleChangeEventfor each entity queued indeferredChangeEntitiesduring a merge, then clears the queue. Called when the outermost merge unwinds so listeners see one event per entity, after all of the merge's writes are in place. -
recordMergeApplied
Records that the merge itself wrote the given (entity, attribute) during the active merge. A change event for an (entity, attribute) that is not recorded is a listener-injected user edit and must be tracked; seeisMergeApplied(java.lang.Object, java.lang.String). No-op outside a merge. -
isMergeApplied
Whether the merge itself wrote the given (entity, attribute) during the active merge (seerecordMergeApplied(java.lang.Object, java.lang.String)). Used to tell the merge's own writes from listener-injected user edits. -
find
Description copied from interface:DataContextReturns an entity instance by its class and id.- Specified by:
findin interfaceDataContext- Returns:
- entity instance or null if there is no such entity in the context
-
find
public <T> @Nullable T find(T entity) Description copied from interface:DataContextReturns the instance of entity with the same id if it exists in this context.- Specified by:
findin interfaceDataContext- Returns:
- entity instance or null if there is no such entity in the context
-
contains
Description copied from interface:DataContextReturns true if the context contains the given entity (distinguished by its class and id).- Specified by:
containsin interfaceDataContext
-
merge
Description copied from interface:DataContextMerge the given entity into the context. The whole object graph with all references will be merged.If an entity with the same identifier already exists in the context, the passed entity state is copied into it and the existing instance is returned. Otherwise, a copy of the passed instance is registered in the context and returned.
If the given instance is new and the context doesn't contain an instance with the same identifier, the context will save the new instance on
DataContext.save(). Otherwise, even if some attributes of the merged instance are changed as a result of copying the state of the passed instance, the merged instance will not be saved. Such modifications are considered as a result of loading more fresh state from the database.WARNING: use the returned value because it is always a different object instance. The only case when you get the same instance is if the input was previously returned from the same context as a result of
DataContext.find(Class, Object)ormerge().- Specified by:
mergein interfaceDataContext- Parameters:
entity- instance to mergeoptions- merge options- Returns:
- the instance which is tracked by the context
-
merge
public <T> T merge(T entity) Description copied from interface:DataContextSame asDataContext.merge(Object, MergeOptions)with default options.- Specified by:
mergein interfaceDataContext
-
merge
Description copied from interface:DataContextMerge the given entities into the context. The whole object graph for each element of the collection with all references will be merged.Same as
DataContext.merge(Object)but for a collection of instances.- Specified by:
mergein interfaceDataContext- Returns:
- set of instances tracked by the context
-
merge
Description copied from interface:DataContextMerge the given entities into the context. The whole object graph for each element of the collection with all references will be merged.Same as
DataContext.merge(Object, MergeOptions)but for a collection of instances.- Specified by:
mergein interfaceDataContext- Returns:
- set of instances tracked by the context
-
internalMerge
-
makeKey
-
copyEntity
-
mergeState
-
mergeDatatypeProperties
protected void mergeDatatypeProperties(Object srcEntity, Object dstEntity, MetaClass metaClass, boolean srcNew, boolean dstNew, boolean isRoot, MergeOptions options) Copies the loaded datatype and element-collection properties from the source to the destination instance, honouring the dirty-aware merge rule (a destination attribute with an unsaved user edit is never overwritten; a fresh merge rebaselines it instead). Element collections are wrapped in an observable collection so later mutations are tracked. -
mergeReferenceProperties
protected void mergeReferenceProperties(Object srcEntity, Object dstEntity, MetaClass metaClass, boolean srcNew, boolean isRoot, MergeOptions options, Map<Object, Object> mergedMap) Copies the loaded reference and to-many properties from the source to the destination instance, recursively merging each reached node into the context graph. Delegates the dirty-aware special cases toskipOrRebaselineDirtyReference(java.lang.Object, io.jmix.core.metamodel.model.MetaProperty, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions, java.util.Map<java.lang.Object, java.lang.Object>)andmergeUnloadedOrNullReference(java.lang.Object, io.jmix.core.metamodel.model.MetaProperty, java.lang.Object, java.util.Map<java.lang.Object, java.lang.Object>, io.jmix.flowui.model.MergeOptions), and collections tomergeList/mergeSet. Embedded references get a change listener installed. -
skipOrRebaselineDirtyReference
protected boolean skipOrRebaselineDirtyReference(Object dstEntity, MetaProperty property, @Nullable Object value, boolean isRoot, MergeOptions options, Map<Object, Object> mergedMap) Applies the dirty-aware merge rule to a reference or to-many property: when the destination attribute carries an unsaved user edit (including a dirty dotted path under an embedded reference), the incoming value is not installed. Returnstrueto tellmergeReferenceProperties(java.lang.Object, java.lang.Object, io.jmix.core.metamodel.model.MetaClass, boolean, boolean, io.jmix.flowui.model.MergeOptions, java.util.Map<java.lang.Object, java.lang.Object>)to skip the property. A fresh merge still rebaselines the edit against the incoming value, and any skipped incoming node is still merged into the context graph. -
mergeUnloadedOrNullReference
protected void mergeUnloadedOrNullReference(Object dstEntity, MetaProperty property, @Nullable Object value, Map<Object, Object> mergedMap, MergeOptions options) Installs a reference/to-many value when the source side is loaded but the destination side is not yet loaded (or the incoming value is null). A null value is set directly; otherwise the reached node(s) are merged so the installed value holds managed instances, a collection is wrapped observable with a tracker baseline, and the attribute is marked loaded. Embedded properties are handled by the loaded-destination path, not here. -
markLoaded
Marks an attribute as loaded on the entity's loaded-state info, soisLoadedreflects a value that is present in memory because it was set (a user edit) or installed by a merge, rather than lazily materialized. No-op for entities without aLoadedPropertiesInfo(e.g. DTOs). -
reapplySetLoaded
Re-asserts the set-loaded markers of an entity into its currentLoadedPropertiesInfo, so a value present in memory because it was set or merge-installed keeps reporting loaded after a fresh merge replaces the loaded-state cache with a narrower source's (seemergeLoadedPropertiesInfo(java.lang.Object, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions, boolean)). Writes only positive entries, so it can never turn a genuinely-unloaded attribute loaded. No-op for entities without a cache. -
isOverridingApplied
Whether the given property of the given instance was already written from the child by the root visit of the activemergeFromChild(Object, Set)call, so this later visit must not write it again. The source graph can hold another java instance of the same entity - a collection materialized outside this context, for example - carrying the value from before the child's edit; merging that instance onto the same managed instance would silently revert the edit. The parent context's own dirty-skip rule does not cover these attributes: they are marked dirty here only once the merge has finished. -
isOverriding
Whether the dirty-protection of the given property of the merge root is suspended by the currentmergeFromChild(Object, Set)call. A plain property is overridden when it is among the child's dirty attributes; an embedded property is also overridden when any child dirty attribute is a dotted path under it ('address.city'overrides the protection of'address'). -
getDirtyEmbeddedPaths
Dotted attribute paths ('address.city') of the given embedded property that are dirty on the owning managed instance. User edits to embedded sub-attributes are tracked on the owner under such paths (seeDataContextImpl.EmbeddedPropertyChangeListener). -
rebaselineEmbedded
protected void rebaselineEmbedded(Object dstEntity, String propertyName, @Nullable Object incomingEmbedded, Set<String> dirtyEmbeddedPaths) Fresh-merge rebaselining for an embedded property whose copy was skipped because the owner carries dirty state for it: the embedded reference entry itself (if dirty) and each dirty dotted sub-attribute path, using the sub-attribute values of the incoming (unmanaged) embedded instance. -
setPropertyValue
-
setPropertyValue
protected void setPropertyValue(Object entity, MetaProperty property, @Nullable Object value, boolean checkEquals) -
copySystemState
-
mergeSystemState
protected void mergeSystemState(Object srcEntity, Object dstEntity, boolean isRoot, MergeOptions options) -
isColdResetTarget
protected boolean isColdResetTarget(Object dstEntity, boolean isRoot, MergeOptions options, boolean dstExisted) Whether this is a root non-fresh or a fresh merge onto a pre-existing managed instance whose loaded-state info is the caching kind. Such an instance carries source-relative negatives cached at earlier merges, and its fetch group was just unioned with the source's inmergeSystemState(java.lang.Object, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions). In both cases the loaded-state cache is recomputed from that unioned fetch group (blanked before the copy loops inresetLoadedInfoBeforeCopy(java.lang.Object, boolean)) instead of being replaced with the source's, so a fetched attribute the narrower source omits is not reverted to unloaded by a copied source negative. -
isReferenceSource
Whether the source is a reference returned byDataManager.getReference()or a copy of one. Such a source never makes the destination less loaded. -
isReferenceTarget
Whether the destination is a pre-existing reference. It has no unfetched state, so every attribute loaded in the source can be copied into it; the setters mark the copied attributes loaded. -
isEmbeddedToInstall
protected boolean isEmbeddedToInstall(Object srcEntity, Object dstEntity, MetaProperty property, boolean isRoot, MergeOptions options) Whether a loaded embedded value must be installed on a destination that does not report it loaded: the destination is a reference, or the source is a reference in a root or fresh merge.mergeUnloadedOrNullReference(java.lang.Object, io.jmix.core.metamodel.model.MetaProperty, java.lang.Object, java.util.Map<java.lang.Object, java.lang.Object>, io.jmix.flowui.model.MergeOptions)skips embedded values. -
resetLoadedInfoBeforeCopy
Blanks the destination's caching loaded-state info before the copy loops whencoldResetis set (seeisColdResetTarget(java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions, boolean)), so theirisLoadedchecks recompute from the fetch group just unioned inmergeSystemState(java.lang.Object, java.lang.Object, boolean, io.jmix.flowui.model.MergeOptions)rather than from a stale cached negative. No-op otherwise. -
mergeLoadedPropertiesInfo
protected void mergeLoadedPropertiesInfo(Object srcEntity, Object dstEntity, boolean isRoot, MergeOptions options, boolean coldReset) -
mergeLazyLoadingState
-
mergeList
protected void mergeList(List<Object> list, Object managedEntity, MetaProperty property, boolean replace, MergeOptions options, Map<Object, Object> mergedMap) -
mergeSet
protected void mergeSet(Set<Object> set, Object managedEntity, MetaProperty property, boolean replace, MergeOptions options, Map<Object, Object> mergedMap) -
beginMergeCollection
Marks the given owner entity's collection property as being merged within the active merge() call. Returnsfalseif it is already in progress (a re-entry, caused by a source graph holding multiple java instances of the same id joined by a bidirectional reference), in which case the caller must return early and let the outer mergeList/mergeSet finish populating the collection. -
endMergeCollection
Clears the in-progress marker set bybeginMergeCollection(java.lang.Object, java.lang.String)for the owner's collection property, once its merge finishes. -
wrapLazyValueIntoObservableCollection
protected Collection<Object> wrapLazyValueIntoObservableCollection(Collection<Object> collection, Object notifiedEntity, @Nullable String property) Wraps a collection in an observable list/set that notifiescollectionChanged(java.lang.Object, java.lang.String)on mutation and, when a property is given, snapshots the tracker baseline so a later mutation marks the owner modified. Returns the collection unchanged if it is neither a list nor a set. -
wrapLazyValueIntoObservableCollection
protected Collection<Object> wrapLazyValueIntoObservableCollection(Collection<Object> collection, Object notifiedEntity, @Nullable String property, boolean snapshotBaseline) Same aswrapLazyValueIntoObservableCollection(Collection, Object, String), with control over the baseline snapshot. Snapshotting reads the collection's contents, so it must be suppressed when the collection is an unmaterialized lazy holder: reading it would trigger a lazy load whose contents bypass this context (seemergeLazyLoadingState(java.lang.Object, java.lang.Object)). Without a baseline a later mutation is tracked conservatively as a change of the attribute, which is the correct answer for a collection whose pre-mutation contents were never known here. -
createObservableList
-
createObservableList
-
createObservableSet
-
createObservableSet
-
collectionChanged
Mutation callback for the observable collection wrappers. The merge's own collection writes skip the tracker and defer theirChangeEvent; any other mutation marks the owner modified, updates the tracker's to-many dirty state, and fires (or, inside a merge, defers) aChangeEvent. -
remove
Description copied from interface:DataContextRemoves the entity from the context and registers it as deleted. The entity will be removed from the data store upon subsequent call toDataContext.save().If the given entity is not in the context, nothing happens.
- Specified by:
removein interfaceDataContext
-
removeFromCollections
-
evict
Description copied from interface:DataContextRemoves the entity from the context so the context stops tracking it.If the given entity is not in the context, nothing happens.
- Specified by:
evictin interfaceDataContext
-
evictModified
public void evictModified()Description copied from interface:DataContextClears the lists of created/modified/deleted entities and evicts these entities.- Specified by:
evictModifiedin interfaceDataContext
-
clear
public void clear()Description copied from interface:DataContextEvicts all tracked entities.- Specified by:
clearin interfaceDataContext- See Also:
-
create
Description copied from interface:DataContextCreates an entity instance and merges it into the context.Same as:
Foo foo = dataContext.merge(metadata.create(Foo.class));
- Specified by:
createin interfaceDataContext- Parameters:
entityClass- entity class- Returns:
- a new instance which is tracked by the context
-
removeListeners
-
hasChanges
public boolean hasChanges()Description copied from interface:DataContextReturns true if the context has detected changes in the tracked entities.- Specified by:
hasChangesin interfaceDataContext
-
clearChanges
public void clearChanges()Description copied from interface:DataContextClears the lists of modified and removed entities. After calling this method,DataContext.hasChanges()returns false,DataContext.getModified()andDataContext.getRemoved()return empty sets.- Specified by:
clearChangesin interfaceDataContext
-
isModified
Description copied from interface:DataContextReturns true if the context has detected changes in the given entity.- Specified by:
isModifiedin interfaceDataContext
-
setModified
Description copied from interface:DataContextRegisters or unregisters the given entity as modified.- Specified by:
setModifiedin interfaceDataContext- Parameters:
entity- entity instance which is already merged into the contextmodified- true to register or false to unregister
-
getModified
Description copied from interface:DataContextReturns an immutable set of entities registered as modified.- Specified by:
getModifiedin interfaceDataContext
-
getModifiedAttributes
Description copied from interface:DataContextReturns the names of attributes of the given managed entity that were modified by the user and not yet saved. Empty for unknown or unmodified instances, and for instances registered only viaDataContext.setModified(Object, boolean).- Specified by:
getModifiedAttributesin interfaceDataContext
-
entityBecameDirty
Change-tracker callback: an entity gained its first dirty attribute, so it joinsmodifiedInstances. -
entityBecameClean
Change-tracker callback: an entity lost its last dirty attribute, so it leavesmodifiedInstancesunless it was pinned modified viasetModified(java.lang.Object, boolean)(manuallyModified). -
isRemoved
Description copied from interface:DataContextReturns true if the context has registered removal of the given entity.- Specified by:
isRemovedin interfaceDataContext
-
getRemoved
Description copied from interface:DataContextReturns an immutable set of entities registered for removal.- Specified by:
getRemovedin interfaceDataContext
-
save
Description copied from interface:DataContextSaves changed and removed instances using DataManager or a custom save delegate. After successful save, the context contains updated instances returned from the backend code.- Specified by:
savein interfaceDataContext- Returns:
- set of saved and merged back to the context instances. Does not contain removed instances.
- See Also:
-
save
Description copied from interface:DataContextSaves changed and removed instances using DataManager, custom save delegate or merges them to parent data context if it is set. If reloadSaved is set, merge and reload of saved instances is performed so the context will contain updated instances after successful save.- Specified by:
savein interfaceDataContext- Parameters:
reloadSaved- flag indicating whether to reload and merge entities after save using DataManager- Returns:
- set of saved and merged back to the context instances if reloadSaved is true. Empty set otherwise.
- See Also:
-
addPreSaveListener
Description copied from interface:DataContextAdds a listener toDataContext.PreSaveEvent.You can also add an event listener declaratively using a controller method annotated with
Subscribe:@Subscribe(target = Target.DATA_CONTEXT) protected void onPreSave(DataContext.PreSaveEvent event) { // handle event here }- Specified by:
addPreSaveListenerin interfaceDataContext- Parameters:
listener- listener- Returns:
- subscription
-
addPostSaveListener
Description copied from interface:DataContextAdds a listener toDataContext.PostSaveEvent.You can also add an event listener declaratively using a controller method annotated with
Subscribe:@Subscribe(target = Target.DATA_CONTEXT) protected void onPostSave(DataContext.PostSaveEvent event) { // handle event here }- Specified by:
addPostSaveListenerin interfaceDataContext- Parameters:
listener- listener- Returns:
- subscription
-
getSaveDelegate
Description copied from interface:DataContextReturns a function which will be used to save data instead of standard implementation.- Specified by:
getSaveDelegatein interfaceDataContext
-
setSaveDelegate
Description copied from interface:DataContextSets a function which will be used to save data instead of standard implementation.- Specified by:
setSaveDelegatein interfaceDataContext
-
performSave
-
saveToDataManager
-
filterSavedInstances
-
updateFetchPlans
-
isolate
-
mergeFromChild
Description copied from interface:DataContextInternalMerges an entity saved by a child context into this (parent) context.Unlike a plain
DataContext.merge(Object), the child's dirty attributes override this context's own unsaved edits of the same attributes (the child's later intent wins), and are then registered as dirty here so the parent's eventual save carries them.- Specified by:
mergeFromChildin interfaceDataContextInternal- Parameters:
entity- the entity instance saved by the child contextchildDirtyAttributes- attributes the child tracked as changed for this entity- Returns:
- the managed instance of this context
-
mergeDirtyFromChild
Body ofmergeFromChild(Object, Set)for a non-empty set of child dirty attributes. Runs inside a merge, so theChangeEvents it causes are deferred until the caller unwinds. -
remeasureAgainstBaseline
Re-measures an attribute that was already dirty in this context beforemergeFromChild(java.lang.Object, java.util.Set<java.lang.String>)wrote the child's value onto the managed instance: the attribute keeps this context's own baseline, and the value coming from the child can have returned it to that baseline, which un-dirties it. Never marks an attribute dirty - both tracker calls below only compare against an existing baseline. -
mergeCompositionOwnerFromChild
Description copied from interface:DataContextInternalMerges an entity owning a composition child that a child context saved into this (parent) context.Unlike a plain
DataContext.merge(Object), the owner is also marked as changed forDataContext.isModified(Object), so a reopened editor of the owner keeps this context's instance instead of reloading a stale copy. The owner does not enterDataContext.getModified()and is never persisted on its own.- Specified by:
mergeCompositionOwnerFromChildin interfaceDataContextInternal- Parameters:
owner- the owner instance of the child context- Returns:
- the managed instance of this context
-
valueForBaseline
Baseline-shaped current value of the given attribute of a managed instance, in the formDataContextChangeTrackercompares against: a scalar value as is, a reference as its id, a to-many attribute as the membership bag of its current contents, a dotted path viaEntityValues.getValueEx(Object, String). The root segment of the attribute must be loaded on the instance. -
rootSegment
The first segment of a possibly-dotted attribute path:'address'for'address.city', or the whole string when it has no dot. Used to check the loaded state of the top-level property a dotted (embedded) path belongs to. -
markCompositionOwnersModified
Marks the composition owner chain of a just-merged composition child for reopen protection in this (parent) context. A deep-composition edit propagated from a child context dirties only the edited leaf; the intermediate owners the child never marked would otherwise stay clean, so reopening an intermediate editor reloads a stale instance and loses the unsaved deeper edit. Owners go into compositionModifiedOwners (consulted by isModified), NOT into modifiedInstances, so they are never persisted - saving an aggregate must still persist only the entities that actually changed. -
findCompositionOwner
Resolves the composition owner of a managed instance in this context. Inverse first: a reference whose inverse is a composition points back to the owner. Scan fallback (when no loaded inverse owner is found): a managed instance whose composition property referencesentity. Returns the managed owner instance, ornullif none is found. -
propagateCompositionOwnersToParent
Merges the composition owner chain of a modified instance into the parent context, so the parent's owner instances reference the propagated child. A deep-composition edit dirties only the edited leaf, and detail views normally fetch a nested composition collection without the back-reference to its owner, so merging the leaf alone leaves it unreachable from the parent's owner instance: the parent cannot tell that the owner's subtree changed, and reopening an intermediate editor reloads a stale instance and loses the edit. The chain is resolved in this (child) context, the only place where the composition path from the owner down to the edited leaf is known.The merged owners are marked for reopen protection only (
compositionModifiedOwners) and never added tomodifiedInstances, so an untouched owner is still never persisted. -
saveToParentContext
-
cleanupContextAfterRemoveEntity
-
entityHasReference
-
mergeSaved
-
getAll
-
printContent
-
printEntity
-
printObject
-
getModifiedInstances
- Specified by:
getModifiedInstancesin interfaceDataContextChanges- Returns:
- mutable set of entities registered as modified
-
getRemovedInstances
- Specified by:
getRemovedInstancesin interfaceDataContextChanges- Returns:
- mutable set of entities registered as removed
-
getEntityMetaClass
-
getPrimaryKeyPropertyName
-