@CompileStatic class DirtyCheckingSupport extends java.lang.Object
Support methods for dirty checking
| Modifiers | Name | Description |
|---|---|---|
static java.util.Map |
DIRTY_CLASS_MARKER |
Used internally as a marker. |
| Constructor and description |
|---|
DirtyCheckingSupport() |
| Type Params | Return Type | Name and description |
|---|---|---|
|
static boolean |
areAssociationsDirty(PersistentEntity entity, java.lang.Object instance)Checks whether associations are dirty |
|
static boolean |
areEmbeddedDirty(PersistentEntity entity, java.lang.Object instance)Checks whether embedded associations are dirty |
|
static java.lang.Object |
rewrap(DirtyCheckable parent, java.lang.String property, java.lang.Object oldValue, java.lang.Object newValue)Re-establishes change tracking when a tracked collection or map value is replaced through a generated dirty-checking setter. |
|
static java.util.Collection |
wrap(java.util.Collection coll, DirtyCheckable parent, java.lang.String property)Wraps a collection in dirty checking capability |
|
static java.util.Map |
wrap(java.util.Map map, DirtyCheckable parent, java.lang.String property)Wraps a map in dirty checking capability. |
| Methods inherited from class | Name |
|---|---|
class java.lang.Object |
java.lang.Object#equals(java.lang.Object), java.lang.Object#getClass(), java.lang.Object#hashCode(), java.lang.Object#notify(), java.lang.Object#notifyAll(), java.lang.Object#toString(), java.lang.Object#wait(), java.lang.Object#wait(long), java.lang.Object#wait(long, int) |
Used internally as a marker. Do not use in user code
Checks whether associations are dirty
session - The sessionentity - The entityinstance - The instanceChecks whether embedded associations are dirty
session - The sessionentity - The entityinstance - The instanceRe-establishes change tracking when a tracked collection or map value is replaced through a generated dirty-checking setter.
Interception-based stores (MongoDB et al.) install the DirtyChecking* wrappers when an
entity is decoded and rely on them exclusively — there is no flush-time snapshot
comparison. The generated setter used to store whatever raw value it was handed, so
reassigning a collection property replaced the tracked wrapper with a plain, untracked
collection and every later in-place mutation became invisible to change tracking. The
common defensive re-init if (!entity.items) entity.items = [] triggered this on
every load (an empty tracked collection is falsy in Groovy), and because the new empty
collection equals the old one the assignment itself was never flagged either.
Tracking is only re-established, never introduced: the value being replaced must
already be one of the exact classes a datastore decode installs — a generic wrapper, or
the PersistentList/PersistentSet/PersistentSortedSet a to-many
association decodes into. Anything else is returned untouched: a transient instance, a
store like Hibernate that performs its own snapshot-based dirty checking, or a
store-specific subclass such as the Neo4j collection types. Store-specific wrappers in
particular must NOT be replaced by a generic one:
the store's persister recognises its own types (and treats anything already
dirty-checkable as such), so a generic replacement would permanently disable that store's
relationship handling for the property. Leaving the raw value lets the persister wrap it
in its own type on save, exactly as it did before this method existed.
parent - The dirty-checkable ownerproperty - The property being assignedoldValue - The value being replacednewValue - The value being assignednewValue, wrapped if it replaces a tracked valueWraps a collection in dirty checking capability
coll - The collectionparent - The parentproperty - The propertyWraps a map in dirty checking capability. Returns an already-wrapped map unchanged — without that guard an encoder that write-backs on every save nests one wrapper per save.
map - The mapparent - The parentproperty - The property