Class StateManagerImpl

java.lang.Object
org.datanucleus.state.StateManagerImpl
All Implemented Interfaces:
StateManager, DNStateManager<Persistable>
Direct Known Subclasses:
ReferentialStateManagerImpl

public class StateManagerImpl extends Object implements DNStateManager<Persistable>
Implementation of a StateManager, supporting the bytecode enhancement contract of DataNucleus. Implemented here as one StateManager per Object so adds on functionality particular to each object. All Persistable objects will have a StateManager when they have had communication with the ExecutionContext. They will typically always have an identity also. The exception to that is for embedded/serialised objects.

Embedded/Serialised Objects

An object that is being embedded/serialised in an owning object will NOT have an identity unless the object is subject to a makePersistent() call also. When an object is embedded/serialised and a field is changed, the field will NOT be marked as dirty (unless it is also an object in its own right with an identity). When a field is changed any owning objects are updated so that they can update their tables accordingly.

Performance and Memory

StateManagers are very performance-critical, because for each Persistable object made persistent, there will be one StateManager instance, adding up to the total memory footprint of that object. In heap profiling analysis (cerca 2008), StateManagerImpl showed to consume bytes 169 per StateManager by itself and about 500 bytes per StateManager when taking PC-individual child-object (like the id) referred by the StateManager into account. With small Java objects this can mean a substantial memory overhead and for applications using such small objects can be critical. For this reason the StateManager should always be minimal in memory consumption. Any fields that are only present for some cases should, in general, either be offloaded to the ExecutionContext, or to a separate object if multiple fields. The fields loadedFields and dirtyFields could, arguably, be made BitSet but it isn't clear of the benefit in the typical use-case of smaller array sizes (number of fields in a class), as per https://www.baeldung.com/java-boolean-array-bitset-performance

Commit/Rollback

When the managed object is changed it is saved as savedPC and its state as savedPersistenceFlags and savedLoadedFields. These fields allow it to be rolled-back to an earlier state. Refer to the saveFields and restoreFields methods.
  • Field Details

    • HOLLOWFIELDMANAGER

      protected static final SingleTypeFieldManager HOLLOWFIELDMANAGER
    • FLAG_INSERTING

      protected static final int FLAG_INSERTING
      Whether we are in the process of INSERTING the object to persistence.
      See Also:
    • FLAG_INSERTING_CALLBACKS

      protected static final int FLAG_INSERTING_CALLBACKS
      Whether we are in the process of INSERTING the object from persistence, running callbacks.
      See Also:
    • FLAG_DELETING

      protected static final int FLAG_DELETING
      Whether we are in the process of DELETING the object from persistence.
      See Also:
    • FLAG_EMBEDDED

      protected static final int FLAG_EMBEDDED
      Whether we are managing an embedded object.
      See Also:
    • FLAG_VALIDATING

      protected static final int FLAG_VALIDATING
      Whether we are currently validating the object in the datastore.
      See Also:
    • FLAG_RESTORE_VALUES

      protected static final int FLAG_RESTORE_VALUES
      Whether to restore values at StateManager. If true, overwrites the restore values at tx level.
      See Also:
    • FLAG_STORING_PC

      protected static final int FLAG_STORING_PC
      Flag to signify that we are currently storing the persistable object, so we don't detach it on serialisation.
      See Also:
    • FLAG_NEED_INHERITANCE_VALIDATION

      protected static final int FLAG_NEED_INHERITANCE_VALIDATION
      Whether the managed object needs the inheritance level validating before loading fields.
      See Also:
    • FLAG_POSTINSERT_UPDATE

      protected static final int FLAG_POSTINSERT_UPDATE
      See Also:
    • FLAG_LOADINGFPFIELDS

      protected static final int FLAG_LOADINGFPFIELDS
      See Also:
    • FLAG_POSTLOAD_PENDING

      protected static final int FLAG_POSTLOAD_PENDING
      See Also:
    • FLAG_CHANGING_STATE

      protected static final int FLAG_CHANGING_STATE
      See Also:
    • FLAG_FLUSHED_NEW

      protected static final int FLAG_FLUSHED_NEW
      if the persistable object is new and was flushed to the datastore.
      See Also:
    • FLAG_BECOMING_DELETED

      protected static final int FLAG_BECOMING_DELETED
      See Also:
    • FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER

      protected static final int FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER
      Flag whether this SM is updating the ownership of its embedded/serialised field(s).
      See Also:
    • FLAG_RETRIEVING_DETACHED_STATE

      protected static final int FLAG_RETRIEVING_DETACHED_STATE
      Flag for flags whether we are retrieving detached state from the detached object.
      See Also:
    • FLAG_RESETTING_DETACHED_STATE

      protected static final int FLAG_RESETTING_DETACHED_STATE
      Flag for flags whether we are resetting the detached state.
      See Also:
    • FLAG_ATTACHING

      protected static final int FLAG_ATTACHING
      Flag for flags whether we are in the process of attaching the object.
      See Also:
    • FLAG_DETACHING

      protected static final int FLAG_DETACHING
      Flag for flags whether we are in the process of detaching the object.
      See Also:
    • FLAG_MAKING_TRANSIENT

      protected static final int FLAG_MAKING_TRANSIENT
      Flag for flags whether we are in the process of making transient the object.
      See Also:
    • FLAG_FLUSHING

      protected static final int FLAG_FLUSHING
      Flag for flags whether we are in the process of flushing changes to the object.
      See Also:
    • FLAG_DISCONNECTING

      protected static final int FLAG_DISCONNECTING
      Flag for flags whether we are in the process of disconnecting the object.
      See Also:
    • myPC

      protected Persistable myPC
      The persistable instance managed by this StateManager.
    • flags

      protected int flags
      Bit-packed flags for operational settings (packed into "int" for memory benefit).
    • myEC

      protected ExecutionContext myEC
      The ExecutionContext for this StateManager
    • cmd

      protected AbstractClassMetaData cmd
      the metadata for the class.
    • myInternalID

      protected Object myInternalID
      The object identity in the JVM. Will be "myID" (if set) or otherwise a temporary id based on this StateManager.
    • myID

      protected Object myID
      The object identity in the datastore
    • myLC

      protected LifeCycleState myLC
      The actual LifeCycleState for the persistable instance
    • myVersion

      protected Object myVersion
      Optimistic version, when starting any transaction.
    • transactionalVersion

      protected Object transactionalVersion
      Optimistic version, after insert/update but not yet committed (i.e incremented).
    • persistenceFlags

      protected byte persistenceFlags
      Flags for state stored with the object. Maps onto org.datanucleus.enhancement.Persistable "dnFlags".
    • myFP

      protected FetchPlanForClass myFP
      Fetch plan for the class of the managed object.
    • dirty

      protected boolean dirty
      Indicator for whether the persistable instance is dirty. Note that "dirty" in this case is not equated to being in the P_DIRTY state. The P_DIRTY state means that at least one field in the object has been written by the user during the current transaction, whereas for this parameter, a field is "dirty" if it's been written by the user but not yet updated in the data store. The difference is, it's possible for an object's state to be P_DIRTY, yet have no "dirty" fields because flush() has been called at least once during the transaction.
    • dirtyFields

      protected boolean[] dirtyFields
      indicators for which fields are currently dirty in the persistable instance.
    • loadedFields

      protected boolean[] loadedFields
      indicators for which fields are currently loaded in the persistable instance.
    • currFM

      protected FieldManager currFM
      Current FieldManager.
    • savedState

      protected SavedState savedState
      Saved state, for use during any rollback for reinstating the object.
    • HELPER

      private static final EnhancementHelper HELPER
    • preDeleteLoadedFields

      boolean[] preDeleteLoadedFields
      Copy of the "loadedFields" just before delete was started to avoid reload during delete
  • Constructor Details

    • StateManagerImpl

      public StateManagerImpl(ExecutionContext ec, AbstractClassMetaData cmd)
      Constructor for object of specified type managed by the provided ExecutionContext.
      Parameters:
      ec - ExecutionContext
      cmd - the metadata for the class.
  • Method Details

    • connect

      public void connect(ExecutionContext ec, AbstractClassMetaData cmd)
      Description copied from interface: DNStateManager
      Method to (re)connect this StateManager to the specified ExecutionContext and object type.
      Specified by:
      connect in interface DNStateManager<Persistable>
      Parameters:
      ec - ExecutionContext to connect to
      cmd - Metadata for the persistable class
    • disconnect

      public void disconnect()
      Disconnect from the ExecutionContext and persistable object.
      Specified by:
      disconnect in interface DNStateManager<Persistable>
    • isConnected

      public boolean isConnected()
      Specified by:
      isConnected in interface DNStateManager<Persistable>
    • initialiseForHollow

      public void initialiseForHollow(Object id, FieldValues fv, Class pcClass)
      Initialises a state manager to manage a hollow instance having the given object ID and the given (optional) field values. This constructor is used for creating new instances of existing persistent objects, and consequently shouldn't be used when the StoreManager controls the creation of such objects (such as in an ODBMS).
      Specified by:
      initialiseForHollow in interface DNStateManager<Persistable>
      Parameters:
      id - the JDO identity of the object.
      fv - the initial field values of the object (optional)
      pcClass - Class of the object that this will manage the state for
    • initialiseForHollowPreConstructed

      public void initialiseForHollowPreConstructed(Object id, Persistable pc)
      Initialises a state manager to manage the given hollow instance having the given object ID. Unlike the initialiseForHollow(java.lang.Object, org.datanucleus.store.FieldValues, java.lang.Class) method, this method does not create a new instance and instead takes a pre-constructed instance (such as from an ODBMS).
      Specified by:
      initialiseForHollowPreConstructed in interface DNStateManager<Persistable>
      Parameters:
      id - the identity of the object.
      pc - the object to be managed.
    • initialiseForPersistentClean

      public void initialiseForPersistentClean(Object id, Persistable pc)
      Initialises a state manager to manage the passed persistent instance having the given object ID. Used where we have retrieved a PC object from a datastore directly (not field-by-field), for example on an object datastore. This initialiser will not add StateManagers to all related PCs. This must be done by any calling process. This simply adds the StateManager to the specified object and records the id, setting all fields of the object as loaded.
      Specified by:
      initialiseForPersistentClean in interface DNStateManager<Persistable>
      Parameters:
      id - the identity of the object.
      pc - The object to be managed
    • initialiseForEmbedded

      public void initialiseForEmbedded(Persistable pc, boolean copyPc)
      Initialises a state manager to manage a provided Persistable instance that will be EMBEDDED/SERIALISED into another Persistable object. The instance will not be assigned an identity in the process since it is a SCO.
      Specified by:
      initialiseForEmbedded in interface DNStateManager<Persistable>
      Parameters:
      pc - The Persistable to manage (see copyPc also)
      copyPc - Whether the SM should manage a copy of the passed PC or that one
    • initialiseForEmbedded

      public void initialiseForEmbedded(Class<Persistable> pcClass)
      Initialises a state manager to manage an embedded instance of the specified type. This constructor is used for creating new instances of existing (embedded) persistent objects, and consequently shouldn't be used when the StoreManager controls the creation of such objects (such as in an ODBMS). TODO Consider passing in a FieldValues and set the fields
      Specified by:
      initialiseForEmbedded in interface DNStateManager<Persistable>
      Parameters:
      pcClass - Class of the (embedded) object that this will manage the state for
    • initialiseForPersistentNew

      public void initialiseForPersistentNew(Persistable pc, FieldValues preInsertChanges)
      Initialises a state manager to manage a transient instance that is becoming newly persistent. A new object ID for the instance is obtained from the store manager and the object is inserted in the data store.

      This constructor is used for assigning state managers to existing instances that are transitioning to a persistent state.

      Specified by:
      initialiseForPersistentNew in interface DNStateManager<Persistable>
      Parameters:
      pc - the instance being make persistent.
      preInsertChanges - Any changes to make before inserting
    • initialiseForTransactionalTransient

      public void initialiseForTransactionalTransient(Persistable pc)
      Initialises a state manager to manage a Transactional Transient instance. A new object ID for the instance is obtained from the store manager and the object is inserted in the data store.

      This constructor is used for assigning state managers to Transient instances that are transitioning to a transient clean state.

      Specified by:
      initialiseForTransactionalTransient in interface DNStateManager<Persistable>
      Parameters:
      pc - the instance being make persistent.
    • initialiseForDetached

      public void initialiseForDetached(Persistable pc, Object id, Object version)
      Initialises the StateManager to manage a Persistable object in detached state.
      Specified by:
      initialiseForDetached in interface DNStateManager<Persistable>
      Parameters:
      pc - the detach object.
      id - the identity of the object.
      version - the detached version
    • initialiseForPNewToBeDeleted

      public void initialiseForPNewToBeDeleted(Persistable pc)
      Initialises the StateManager to manage a Persistable object that is not persistent but is about to be deleted.
      Specified by:
      initialiseForPNewToBeDeleted in interface DNStateManager<Persistable>
      Parameters:
      pc - the object to delete
    • initialiseForCachedPC

      public void initialiseForCachedPC(CachedPC cachedPC, Object id)
      Initialise StateManager, assigning the specified id to the object. This is used when getting objects out of the L2 Cache, where they have no StateManager assigned, and returning them as associated with a particular ExecutionContext.
      Specified by:
      initialiseForCachedPC in interface DNStateManager<Persistable>
      Parameters:
      cachedPC - The cached PC object
      id - Id to assign to the Persistable object
    • populateValueGenerationMembers

      private void populateValueGenerationMembers()
      Convenience method to populate all members in the PC object that need their value generating (according to metadata) and that aren't datastore-attributed. This applies not just to PK members (main use-case) but also to any other member (DN extension). Members can be populated only if they are null, dependent on metadata. This method is called once on a PC object, when makePersistent is called.
    • getClassMetaData

      public AbstractClassMetaData getClassMetaData()
      Description copied from interface: DNStateManager
      Accessor for the ClassMetaData for this persistable object.
      Specified by:
      getClassMetaData in interface DNStateManager<Persistable>
      Returns:
      The ClassMetaData.
    • getExecutionContext

      public ExecutionContext getExecutionContext()
      Specified by:
      getExecutionContext in interface DNStateManager<Persistable>
    • getExecutionContextReference

      public ExecutionContextReference getExecutionContextReference()
      Description copied from interface: StateManager
      Return the ExecutionContext that owns this instance.
      Specified by:
      getExecutionContextReference in interface StateManager
      Returns:
      the ExecutionContext that owns this instance
    • getStoreManager

      public StoreManager getStoreManager()
      Specified by:
      getStoreManager in interface DNStateManager<Persistable>
    • getFetchPlanForClass

      public FetchPlanForClass getFetchPlanForClass()
      Description copied from interface: DNStateManager
      Accessor for the FetchPlan for this class.
      Specified by:
      getFetchPlanForClass in interface DNStateManager<Persistable>
      Returns:
      The FetchPlanForClass to be used on all fetches
    • getLifecycleState

      public LifeCycleState getLifecycleState()
      Description copied from interface: DNStateManager
      Accessor for the LifeCycleState of this persistable object.
      Specified by:
      getLifecycleState in interface DNStateManager<Persistable>
      Returns:
      the LifeCycleState
    • getCallbackHandler

      protected CallbackHandler getCallbackHandler()
    • getObject

      public Persistable getObject()
      Description copied from interface: DNStateManager
      Accessor for the persistable object being managed.
      Specified by:
      getObject in interface DNStateManager<Persistable>
      Returns:
      the persistable object
    • getObjectAsPrintable

      public String getObjectAsPrintable()
      Description copied from interface: DNStateManager
      Returns a printable form of the managed object.
      Specified by:
      getObjectAsPrintable in interface DNStateManager<Persistable>
      Returns:
      The object reference for the persistable object.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • isWaitingToBeFlushedToDatastore

      public boolean isWaitingToBeFlushedToDatastore()
      Accessor for whether the instance is newly persistent yet hasnt yet been flushed to the datastore.
      Specified by:
      isWaitingToBeFlushedToDatastore in interface DNStateManager<Persistable>
      Returns:
      Whether not yet flushed to the datastore
    • isRestoreValues

      public boolean isRestoreValues()
      Accessor for whether we are in the process of restoring the values.
      Specified by:
      isRestoreValues in interface DNStateManager<Persistable>
      Returns:
      Whether we are restoring values
    • isChangingState

      protected boolean isChangingState()
    • isInserting

      public boolean isInserting()
      Description copied from interface: DNStateManager
      Tests whether this object is being inserted.
      Specified by:
      isInserting in interface DNStateManager<Persistable>
      Returns:
      true if this instance is inserting.
    • setInserting

      public void setInserting()
      Specified by:
      setInserting in interface DNStateManager<Persistable>
    • setInsertingCallbacks

      public void setInsertingCallbacks()
      Specified by:
      setInsertingCallbacks in interface DNStateManager<Persistable>
    • isDeleting

      public boolean isDeleting()
      Description copied from interface: DNStateManager
      Tests whether this object is being deleted.
      Specified by:
      isDeleting in interface DNStateManager<Persistable>
      Returns:
      true if this instance is being deleted.
    • markForInheritanceValidation

      public void markForInheritanceValidation()
      Description copied from interface: DNStateManager
      Mark the state manager as needing to validate the inheritance of the managed object existence before loading fields.
      Specified by:
      markForInheritanceValidation in interface DNStateManager<Persistable>
    • setTransactionalVersion

      public void setTransactionalVersion(Object version)
      Sets the value for the version column in a transaction not yet committed
      Specified by:
      setTransactionalVersion in interface DNStateManager<Persistable>
      Parameters:
      version - The version
    • getTransactionalVersion

      public Object getTransactionalVersion(Object pc)
      Return the object representing the transactional version of the calling instance.
      Parameters:
      pc - the calling persistable instance
      Returns:
      the object representing the version of the calling instance
    • setVersion

      public void setVersion(Object version)
      Sets the value for the version column in the datastore
      Specified by:
      setVersion in interface DNStateManager<Persistable>
      Parameters:
      version - The version
    • setFlushedNew

      public void setFlushedNew(boolean flag)
      Specified by:
      setFlushedNew in interface DNStateManager<Persistable>
    • isFlushedNew

      public boolean isFlushedNew()
      Description copied from interface: DNStateManager
      Whether this record has been flushed to the datastore in this transaction (i.e called persist() and is in the datastore now). If user has called persist() on it yet not yet persisted then returns false.
      Specified by:
      isFlushedNew in interface DNStateManager<Persistable>
      Returns:
      Whether this is flushed new.
    • isFlushedToDatastore

      public boolean isFlushedToDatastore()
      Description copied from interface: DNStateManager
      Accessor for whether all changes have been written to the datastore.
      Specified by:
      isFlushedToDatastore in interface DNStateManager<Persistable>
      Returns:
      Whether the datastore has all changes
    • setFlushing

      public void setFlushing(boolean flushing)
      Specified by:
      setFlushing in interface DNStateManager<Persistable>
    • isFlushing

      protected boolean isFlushing()
    • markAsFlushed

      public void markAsFlushed()
      Description copied from interface: DNStateManager
      Method to notify the StateManager that the object has now been flushed to the datastore. This is performed when handling inserts or deletes in a batch external to StateManager.
      Specified by:
      markAsFlushed in interface DNStateManager<Persistable>
    • refresh

      public void refresh()
      Method to refresh the object.
      Specified by:
      refresh in interface DNStateManager<Persistable>
    • retrieve

      public void retrieve(boolean fgOnly)
      Method to retrieve the object.
      Specified by:
      retrieve in interface DNStateManager<Persistable>
      Parameters:
      fgOnly - Only load the current fetch group fields
    • makePersistentTransactionalTransient

      public void makePersistentTransactionalTransient()
      Makes Transactional Transient instances persistent.
      Specified by:
      makePersistentTransactionalTransient in interface DNStateManager<Persistable>
    • makeNontransactional

      public void makeNontransactional()
      Method to change the object state to nontransactional.
      Specified by:
      makeNontransactional in interface DNStateManager<Persistable>
    • transitionReadField

      protected void transitionReadField(boolean isLoaded)
      Method to change the object state to read-field.
      Parameters:
      isLoaded - if the field was previously loaded
    • transitionWriteField

      protected void transitionWriteField()
      Method to change the object state to write-field.
    • evict

      public void evict()
      Method to change the object state to evicted.
      Specified by:
      evict in interface DNStateManager<Persistable>
    • preBegin

      public void preBegin(Transaction tx)
      Method invoked just before a transaction starts for the ExecutionContext managing us.
      Specified by:
      preBegin in interface DNStateManager<Persistable>
      Parameters:
      tx - The transaction
    • postCommit

      public void postCommit(Transaction tx)
      This method is invoked just after a commit is performed in a Transaction involving the persistable object managed by this StateManager
      Specified by:
      postCommit in interface DNStateManager<Persistable>
      Parameters:
      tx - The transaction
    • preRollback

      public void preRollback(Transaction tx)
      This method is invoked just before a rollback is performed in a Transaction involving the persistable object managed by this StateManager.
      Specified by:
      preRollback in interface DNStateManager<Persistable>
      Parameters:
      tx - The transaction
    • internalDeletePersistent

      protected void internalDeletePersistent()
      Method to delete the object from the datastore.
    • locate

      public void locate()
      Locate the object in the datastore.
      Specified by:
      locate in interface DNStateManager<Persistable>
      Throws:
      NucleusObjectNotFoundException - if the object doesnt exist.
    • getReferencedPC

      public Persistable getReferencedPC()
      Accessor for the referenced PC object when we are attaching or detaching. When attaching and this is the detached object this returns the newly attached object. When attaching and this is the newly attached object this returns the detached object. When detaching and this is the newly detached object this returns the attached object. When detaching and this is the attached object this returns the newly detached object.
      Specified by:
      getReferencedPC in interface DNStateManager<Persistable>
      Returns:
      The referenced object (or null).
    • areFieldsLoaded

      protected boolean areFieldsLoaded(int[] fieldNumbers)
      Accessor for whether all of the specified field numbers are loaded.
      Parameters:
      fieldNumbers - The field numbers to check
      Returns:
      Whether the specified fields are all loaded.
    • unloadField

      public void unloadField(int fieldNumber)
      Description copied from interface: DNStateManager
      Mark the specified field as not loaded so that it will be reloaded on next access.
      Specified by:
      unloadField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Absolute field number
    • unloadNonFetchPlanFields

      public void unloadNonFetchPlanFields()
      Description copied from interface: DNStateManager
      Method that will unload all fields that are not in the FetchPlan.
      Specified by:
      unloadNonFetchPlanFields in interface DNStateManager<Persistable>
    • markFieldsAsLoaded

      public void markFieldsAsLoaded(int[] fieldNumbers)
      Description copied from interface: DNStateManager
      Convenience method to mark all fields as "loaded". NOTE: This is a convenience mutator only to be used when you know what you are doing. Currently only used by the XML plugin.
      Specified by:
      markFieldsAsLoaded in interface DNStateManager<Persistable>
      Parameters:
      fieldNumbers - The field numbers to mark as loaded
    • markPKFieldsAsLoaded

      protected void markPKFieldsAsLoaded()
      Convenience method to mark PK fields as loaded (if using app id).
    • updateLevel2CacheForFields

      protected void updateLevel2CacheForFields(int[] fieldNumbers)
      Convenience method to update a Level2 cached version of this object if cacheable and has not been modified during this transaction.
      Parameters:
      fieldNumbers - Numbers of fields to update in L2 cached object
    • loadFieldsFromLevel2Cache

      protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers)
      Convenience method to retrieve field values from an L2 cached object if they are loaded in that object. If the object is not in the L2 cache then just returns, and similarly if the required fields aren't available.
      Parameters:
      fieldNumbers - Numbers of fields to load from the L2 cache
      Returns:
      The fields that couldn't be loaded
    • loadFieldsInFetchPlan

      public void loadFieldsInFetchPlan(FetchPlanState state)
      Method to load all unloaded fields in the FetchPlan. Recurses through the FetchPlan objects and loads fields of sub-objects where needed. Used as a precursor to detaching objects at commit since fields can't be loaded during the postCommit phase when the detach actually happens.
      Specified by:
      loadFieldsInFetchPlan in interface DNStateManager<Persistable>
      Parameters:
      state - The FetchPlan state
    • loadFieldFromDatastore

      public void loadFieldFromDatastore(int fieldNumber)
      Convenience method to load a field from the datastore. Used in attaching fields and checking their old values (so we don't want any postLoad method being called). TODO Merge this with one of the loadXXXFields methods.
      Specified by:
      loadFieldFromDatastore in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - The field number. If fieldNumber is -1 then this means call loadFieldsFromDatastore(null);
    • loadFieldsFromDatastore

      protected void loadFieldsFromDatastore(int[] fieldNumbers)
      Convenience method to load fields from the datastore. Note that if the fieldNumbers is null/empty we still should call the persistence handler since it may mean that the version field needs loading.
      Parameters:
      fieldNumbers - The field numbers.
    • getFieldNumbersOfLoadedOrDirtyFields

      protected int[] getFieldNumbersOfLoadedOrDirtyFields(boolean[] loadedFields, boolean[] dirtyFields)
      Convenience accessor to return the field numbers for the input loaded and dirty field arrays.
      Parameters:
      loadedFields - Fields that were detached with the object
      dirtyFields - Fields that have been modified while detached
      Returns:
      The field numbers of loaded or dirty fields
    • getDirtyFields

      public boolean[] getDirtyFields()
      Creates a copy of the dirtyFields bitmap.
      Specified by:
      getDirtyFields in interface DNStateManager<Persistable>
      Returns:
      a copy of the dirtyFields bitmap.
    • getDirtyFieldNumbers

      public int[] getDirtyFieldNumbers()
      Accessor for the field numbers of all dirty fields.
      Specified by:
      getDirtyFieldNumbers in interface DNStateManager<Persistable>
      Returns:
      Absolute field numbers of the dirty fields in this instance.
    • getLoadedFields

      public boolean[] getLoadedFields()
      Accessor for the fields
      Specified by:
      getLoadedFields in interface DNStateManager<Persistable>
      Returns:
      boolean array of loaded state in order of absolute field numbers
    • getLoadedFieldNumbers

      public int[] getLoadedFieldNumbers()
      Accessor for the field numbers of all loaded fields in this managed instance.
      Specified by:
      getLoadedFieldNumbers in interface DNStateManager<Persistable>
      Returns:
      Field numbers of all (currently) loaded fields
    • getAllFieldsLoaded

      public boolean getAllFieldsLoaded()
      Returns whether all fields are loaded.
      Specified by:
      getAllFieldsLoaded in interface DNStateManager<Persistable>
      Returns:
      Returns true if all fields are loaded.
    • getDirtyFieldNames

      public String[] getDirtyFieldNames()
      Convenience accessor for the names of the fields that are dirty.
      Specified by:
      getDirtyFieldNames in interface DNStateManager<Persistable>
      Returns:
      Names of the dirty fields
    • getLoadedFieldNames

      public String[] getLoadedFieldNames()
      Convenience accessor for the names of the fields that are loaded.
      Specified by:
      getLoadedFieldNames in interface DNStateManager<Persistable>
      Returns:
      Names of the loaded fields
    • isFieldLoaded

      public boolean isFieldLoaded(int fieldNumber)
      Accessor for whether a field is currently loaded. Just returns the status, unlike "isLoaded" which also loads it if not.
      Specified by:
      isFieldLoaded in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - The (absolute) field number
      Returns:
      Whether it is loaded
    • storeFieldValue

      public void storeFieldValue(int fieldNumber, Object value)
      Description copied from interface: DNStateManager
      Method to store the value for the specified field. This is for use with fields that are of type Persistable, and we stored the "id" of the related object in case they need loading later rather than instantiating now.
      Specified by:
      storeFieldValue in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Absolute field number
      value - The value to store (FK "id")
    • clearFieldsByNumbers

      protected void clearFieldsByNumbers(int[] fieldNumbers)
    • clearDirtyFlags

      protected void clearDirtyFlags()
      Method to clear all dirty flags on the object.
    • clearDirtyFlags

      protected void clearDirtyFlags(int[] fieldNumbers)
      Method to clear all dirty flags on the object.
      Parameters:
      fieldNumbers - the fields to clear
    • isEmbedded

      public boolean isEmbedded()
      Convenience accessor for whether this StateManager manages an embedded/serialised object.
      Specified by:
      isEmbedded in interface DNStateManager<Persistable>
      Returns:
      Whether the managed object is embedded/serialised.
    • providedBooleanField

      public void providedBooleanField(Persistable ignored, int fieldNumber, boolean currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedBooleanField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedByteField

      public void providedByteField(Persistable ignored, int fieldNumber, byte currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedByteField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedCharField

      public void providedCharField(Persistable ignored, int fieldNumber, char currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedCharField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedDoubleField

      public void providedDoubleField(Persistable ignored, int fieldNumber, double currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedDoubleField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedFloatField

      public void providedFloatField(Persistable ignored, int fieldNumber, float currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedFloatField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedIntField

      public void providedIntField(Persistable ignored, int fieldNumber, int currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedIntField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedLongField

      public void providedLongField(Persistable ignored, int fieldNumber, long currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedLongField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedShortField

      public void providedShortField(Persistable ignored, int fieldNumber, short currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedShortField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedStringField

      public void providedStringField(Persistable ignored, int fieldNumber, String currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedStringField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • providedObjectField

      public void providedObjectField(Persistable ignored, int fieldNumber, Object currentValue)
      This method is called from the associated persistable when its dnProvideFields() method is invoked. Its purpose is to provide the value of the specified field to the StateManager.
      Specified by:
      providedObjectField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
    • replacingBooleanField

      public boolean replacingBooleanField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a boolean field.
      Specified by:
      replacingBooleanField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingByteField

      public byte replacingByteField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a byte field.
      Specified by:
      replacingByteField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingCharField

      public char replacingCharField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a char field.
      Specified by:
      replacingCharField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingDoubleField

      public double replacingDoubleField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a double field.
      Specified by:
      replacingDoubleField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingFloatField

      public float replacingFloatField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a float field.
      Specified by:
      replacingFloatField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingIntField

      public int replacingIntField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a int field.
      Specified by:
      replacingIntField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingLongField

      public long replacingLongField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a long field.
      Specified by:
      replacingLongField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingShortField

      public short replacingShortField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a short field.
      Specified by:
      replacingShortField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingStringField

      public String replacingStringField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of a String field.
      Specified by:
      replacingStringField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • replacingObjectField

      public Object replacingObjectField(Persistable ignored, int fieldNumber)
      This method is invoked by the persistable object's dnReplaceField() method to refresh the value of an Object field.
      Specified by:
      replacingObjectField in interface StateManager
      Parameters:
      ignored - the calling persistable instance
      fieldNumber - the field number
      Returns:
      the new value for the field
    • registerTransactional

      public void registerTransactional()
      Registers the pc class in the cache
      Specified by:
      registerTransactional in interface DNStateManager<Persistable>
    • setAssociatedValue

      public void setAssociatedValue(Object key, Object value)
      Description copied from interface: DNStateManager
      Method to set an associated value stored with this object. This is for a situation such as in ORM where this object can have an "external" foreign-key provided by an owning object (e.g 1-N uni relation and this is the element with no knowledge of the owner, so the associated value is the FK value).
      Specified by:
      setAssociatedValue in interface DNStateManager<Persistable>
      Parameters:
      key - Key for the value
      value - The associated value
    • getAssociatedValue

      public Object getAssociatedValue(Object key)
      Description copied from interface: DNStateManager
      Accessor for the value of an external field. This is for a situation such as in ORM where this object can have an "external" foreign-key provided by an owning object (e.g 1-N uni relation and this is the element with no knowledge of the owner, so the associated value is the FK value).
      Specified by:
      getAssociatedValue in interface DNStateManager<Persistable>
      Parameters:
      key - The key for this associated information
      Returns:
      The value stored (if any) against this key
    • removeAssociatedValue

      public void removeAssociatedValue(Object key)
      Description copied from interface: DNStateManager
      Method to remove the associated value with the specified key (if it exists).
      Specified by:
      removeAssociatedValue in interface DNStateManager<Persistable>
      Parameters:
      key - The key
    • containsAssociatedValue

      public boolean containsAssociatedValue(Object key)
      Description copied from interface: DNStateManager
      Accessor for whether the specified associated value key is present.
      Specified by:
      containsAssociatedValue in interface DNStateManager<Persistable>
      Parameters:
      key - The key
      Returns:
      Whether it is present
    • enlistInTransaction

      public void enlistInTransaction()
      Method to enlist the managed object in the current transaction.
      Specified by:
      enlistInTransaction in interface DNStateManager<Persistable>
    • evictFromTransaction

      public void evictFromTransaction()
      Method to evict the managed object from the current transaction.
      Specified by:
      evictFromTransaction in interface DNStateManager<Persistable>
    • replaceStateManager

      protected void replaceStateManager(Persistable pc, StateManager sm)
      Utility to update the passed object with the passed StateManager (can be null).
      Parameters:
      pc - The object to update
      sm - The new state manager
    • replacingStateManager

      public StateManager replacingStateManager(Persistable pc, StateManager sm)
      Replace the current value of StateManager in the Persistable object.

      This method is called by the Persistable whenever dnReplaceStateManager is called and there is already an owning StateManager. This is a security precaution to ensure that the owning StateManager is the only source of any change to its reference in the Persistable.

      Specified by:
      replacingStateManager in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      sm - the proposed new value for the StateManager
      Returns:
      the new value for the StateManager
    • replaceManagedPC

      public void replaceManagedPC(Persistable pc)
      Method that replaces the PC managed by this StateManager to be the supplied object. This is used when we want to get an object for an id and create a Hollow object, and then validate against the datastore. This validation can pull in a new object graph from the datastore (e.g for an ODBMS).
      Specified by:
      replaceManagedPC in interface DNStateManager<Persistable>
      Parameters:
      pc - The persistable to use
    • isDirty

      public boolean isDirty(Persistable pc)
      Tests whether this object is dirty. Instances that have been modified, deleted, or newly made persistent in the current transaction return true. Transient nontransactional instances return false (JDO spec).
      Specified by:
      isDirty in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      true if this instance has been modified in current transaction.
      See Also:
    • isTransactional

      public boolean isTransactional(Persistable pc)
      Tests whether this object is transactional. Instances that respect transaction boundaries return true. These instances include transient instances made transactional as a result of being the target of a makeTransactional method call; newly made persistent or deleted persistent instances; persistent instances read in data store transactions; and persistent instances modified in optimistic transactions.

      Transient nontransactional instances return false.

      Specified by:
      isTransactional in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      true if this instance is transactional.
    • isPersistent

      public boolean isPersistent(Persistable pc)
      Tests whether this object is persistent. Instances whose state is stored in the data store return true. Transient instances return false.
      Specified by:
      isPersistent in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      true if this instance is persistent.
    • isNew

      public boolean isNew(Persistable pc)
      Tests whether this object has been newly made persistent. Instances that have been made persistent in the current transaction return true.

      Transient instances return false.

      Specified by:
      isNew in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      true if this instance was made persistent in the current transaction.
    • isDeleted

      public boolean isDeleted()
      Description copied from interface: DNStateManager
      Tests whether this object has been deleted. Instances that have been deleted in the current transaction return true. Transient instances return false.
      Specified by:
      isDeleted in interface DNStateManager<Persistable>
      Returns:
      true if this instance was deleted in the current transaction.
    • isDeleted

      public boolean isDeleted(Persistable pc)
      Tests whether this object has been deleted. Instances that have been deleted in the current transaction return true.

      Transient instances return false.

      Specified by:
      isDeleted in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      true if this instance was deleted in the current transaction.
    • getVersion

      public Object getVersion(Persistable pc)
      Return the object representing the version of the calling instance.
      Specified by:
      getVersion in interface StateManager
      Parameters:
      pc - the calling persistable instance
      Returns:
      the object representing the version of the calling instance
    • isVersionLoaded

      public boolean isVersionLoaded()
      Method to return if the version is loaded. If the class represented is not versioned then returns true
      Specified by:
      isVersionLoaded in interface DNStateManager<Persistable>
      Returns:
      Whether it is loaded.
    • getVersion

      public Object getVersion()
      Method to return the current version of the managed object.
      Specified by:
      getVersion in interface DNStateManager<Persistable>
      Returns:
      The version
    • getTransactionalVersion

      public Object getTransactionalVersion()
      Return the transactional version of the managed object.
      Specified by:
      getTransactionalVersion in interface DNStateManager<Persistable>
      Returns:
      Version of the managed instance at this point in the transaction
    • clearFields

      public void clearFields()
      Method to clear all fields of the object.
      Specified by:
      clearFields in interface DNStateManager<Persistable>
    • clearNonPrimaryKeyFields

      public void clearNonPrimaryKeyFields()
      Method to clear all fields that are not part of the primary key of the object.
      Specified by:
      clearNonPrimaryKeyFields in interface DNStateManager<Persistable>
    • clearLoadedFlags

      public void clearLoadedFlags()
      Method to clear all loaded flags on the object. Note that the contract of this method implies, especially for object database backends, that the memory form of the object is outdated. Thus, for features like implicit saving of dirty object subgraphs should be switched off for this PC, even if the object actually looks like being dirty (because it is being changed to null values).
      Specified by:
      clearLoadedFlags in interface DNStateManager<Persistable>
    • replacingFlags

      public byte replacingFlags(Persistable pc)
      The StateManager uses this method to supply the value of dnFlags to the associated persistable instance.
      Specified by:
      replacingFlags in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      Returns:
      the value of dnFlags to be stored in the Persistable instance
    • provideField

      public Object provideField(int fieldNumber)
      Method to return the current value of a particular field.
      Specified by:
      provideField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Number of field
      Returns:
      The value of the field
    • provideField

      protected Object provideField(Persistable pc, int fieldNumber)
      Method to retrieve the value of a field from the PC object. Assumes that it is loaded.
      Parameters:
      pc - The PC object
      fieldNumber - Number of field
      Returns:
      The value of the field
    • provideFields

      public void provideFields(int[] fieldNumbers, FieldManager fm)
      Called from the StoreManager after StoreManager.update() is called to obtain updated values from the Persistable associated with this StateManager.
      Specified by:
      provideFields in interface DNStateManager<Persistable>
      Parameters:
      fieldNumbers - An array of field numbers to be updated by the Store
      fm - The updated values are stored in this object. This object is only valid for the duration of this call.
    • setBooleanField

      public void setBooleanField(Persistable pc, int fieldNumber, boolean currentValue, boolean newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setBooleanField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setByteField

      public void setByteField(Persistable pc, int fieldNumber, byte currentValue, byte newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setByteField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setCharField

      public void setCharField(Persistable pc, int fieldNumber, char currentValue, char newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setCharField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setDoubleField

      public void setDoubleField(Persistable pc, int fieldNumber, double currentValue, double newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setDoubleField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setFloatField

      public void setFloatField(Persistable pc, int fieldNumber, float currentValue, float newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setFloatField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setIntField

      public void setIntField(Persistable pc, int fieldNumber, int currentValue, int newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setIntField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setLongField

      public void setLongField(Persistable pc, int fieldNumber, long currentValue, long newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setLongField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setShortField

      public void setShortField(Persistable pc, int fieldNumber, short currentValue, short newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setShortField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setStringField

      public void setStringField(Persistable pc, int fieldNumber, String currentValue, String newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setStringField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • setObjectField

      public void setObjectField(Persistable pc, int fieldNumber, Object currentValue, Object newValue)
      This method is called by the associated Persistable when the corresponding mutator method (setXXX()) is called on the Persistable.
      Specified by:
      setObjectField in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the field number
      currentValue - the current value of the field
      newValue - the new value for the field
    • updateField

      protected void updateField(Persistable pc, int fieldNumber, Object value)
      Convenience method to perform the update of a field value when a setter is invoked. Called by setXXXField methods.
      Parameters:
      pc - The PC object
      fieldNumber - The field number
      value - The new value
    • replaceField

      protected void replaceField(Persistable pc, int fieldNumber, Object value)
      Method to change the value of a field in the PC object.
      Parameters:
      pc - The PC object
      fieldNumber - Number of field
      value - The new value of the field
    • disconnectClone

      protected boolean disconnectClone(Persistable pc)
      Method to disconnect any cloned persistence capable objects from their StateManager.
      Parameters:
      pc - The Persistable object
      Returns:
      Whether the object was disconnected.
    • retrieveDetachState

      public void retrieveDetachState(DNStateManager sm)
      Convenience method to retrieve the detach state from the passed StateManager's object.
      Specified by:
      retrieveDetachState in interface DNStateManager<Persistable>
      Parameters:
      sm - StateManager
    • resetDetachState

      public void resetDetachState()
      Convenience method to reset the detached state in the current object.
      Specified by:
      resetDetachState in interface DNStateManager<Persistable>
    • replacingDetachedState

      public Object[] replacingDetachedState(Detachable pc, Object[] currentState)
      Method to update the "detached state" in the detached object to obtain the "detached state" from the detached object, or to reset it (to null).
      Specified by:
      replacingDetachedState in interface StateManager
      Parameters:
      pc - The Persistable being updated
      currentState - The current state values
      Returns:
      The detached state to assign to the object
    • makeDirty

      public void makeDirty(int fieldNumber)
      Marks the given field dirty.
      Specified by:
      makeDirty in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - The no of field to mark as dirty.
    • makeDirty

      public void makeDirty(Persistable pc, String fieldName)
      Mark the associated persistable field dirty.
      Specified by:
      makeDirty in interface StateManager
      Parameters:
      pc - the calling persistable instance
      fieldName - the name of the field
    • getInternalObjectId

      public Object getInternalObjectId()
      Accessor for the internal object id of the object we are managing. This will return the "id" if it has been set, otherwise a temporary id (IdentityReference).
      Specified by:
      getInternalObjectId in interface DNStateManager<Persistable>
      Returns:
      The internal object id
    • getObjectId

      public Object getObjectId(Persistable pc)
      Return the object representing the persistent identity of the calling instance. According to the JDO specification, if the persistent identity is being changed in the current transaction, this method returns the persistent identify as of the beginning of the transaction. In DataNucleus we don't allow change of identity so this is always the same as the result of getExternalObjectId(Persistable).
      Specified by:
      getObjectId in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      Returns:
      the object representing the persistent identity of the calling instance
    • getTransactionalObjectId

      public Object getTransactionalObjectId(Persistable pc)
      Return the object representing the persistent identity of the calling instance. If the persistent identity is being changed in the current transaction, this method returns the current identity as changed in the transaction. In DataNucleus we don't allow change of identity so this is always the same as the result of getObjectId(Persistable).
      Specified by:
      getTransactionalObjectId in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      Returns:
      the object representing the persistent identity of the calling instance
    • getExternalObjectId

      public Object getExternalObjectId()
      Description copied from interface: DNStateManager
      Return an object id that the user can use.
      Specified by:
      getExternalObjectId in interface DNStateManager<Persistable>
      Returns:
      the object id
    • setIdentity

      private void setIdentity(boolean afterPreStore)
      Utility to set the identity for the Persistable object. Creates the identity instance if the required PK field(s) are all already set (by the user, or by a value-strategy). If the identity is set in the datastore (sequence, autoassign, etc) then this will not set the identity.
      Parameters:
      afterPreStore - Whether preStore has (just) been invoked
    • setPostStoreNewObjectId

      public void setPostStoreNewObjectId(Object id)
      If the id is obtained after inserting the object into the database, set new a new id for persistent classes (for example, increment).
      Specified by:
      setPostStoreNewObjectId in interface DNStateManager<Persistable>
      Parameters:
      id - the id received from the datastore
    • loadFieldValues

      public void loadFieldValues(FieldValues fv)
      Convenience method to load the passed field values. Loads the fields using any required fetch plan and calls dnPostLoad() as appropriate.
      Specified by:
      loadFieldValues in interface DNStateManager<Persistable>
      Parameters:
      fv - Field Values to load (including any fetch plan to use when loading)
    • loadSpecifiedFields

      protected void loadSpecifiedFields(int[] fieldNumbers)
      Fetch the specified fields from the database.
      Parameters:
      fieldNumbers - the numbers of the field(s) to fetch.
    • loadField

      public void loadField(int fieldNumber)
      Convenience method to load the specified field if not loaded.
      Specified by:
      loadField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Absolute field number
    • loadStoredField

      public boolean loadStoredField(int fieldNumber)
      Description copied from interface: DNStateManager
      Convenience method to load the specified field from the stored associated value cache if available.
      Specified by:
      loadStoredField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Absolute field number
      Returns:
      whether it was loaded from stored cache values
    • loadUnloadedRelationFields

      public void loadUnloadedRelationFields()
      Description copied from interface: DNStateManager
      Loads (from the database) all unloaded fields that store relations.
      Specified by:
      loadUnloadedRelationFields in interface DNStateManager<Persistable>
    • loadUnloadedFields

      public void loadUnloadedFields()
      Description copied from interface: DNStateManager
      Fetch from the database all fields that are not currently loaded regardless of whether they are in the current fetch group or not. Called by lifecycle transitions.
      Specified by:
      loadUnloadedFields in interface DNStateManager<Persistable>
    • loadUnloadedFieldsInFetchPlan

      public void loadUnloadedFieldsInFetchPlan()
      Description copied from interface: DNStateManager
      Loads (from the database) all unloaded fields that are in the current FetchPlan.
      Specified by:
      loadUnloadedFieldsInFetchPlan in interface DNStateManager<Persistable>
    • loadUnloadedFieldsInFetchPlanAndVersion

      protected void loadUnloadedFieldsInFetchPlanAndVersion()
      Fetch from the database all fields in current fetch plan that are not currently loaded as well as the version. Called by lifecycle transitions.
    • loadUnloadedFieldsOfClassInFetchPlan

      public void loadUnloadedFieldsOfClassInFetchPlan(FetchPlan fetchPlan)
      Description copied from interface: DNStateManager
      Loads (from the database) all unloaded fields of the managed class that are in the specified FetchPlan.
      Specified by:
      loadUnloadedFieldsOfClassInFetchPlan in interface DNStateManager<Persistable>
      Parameters:
      fetchPlan - The FetchPlan
    • refreshFieldsInFetchPlan

      public void refreshFieldsInFetchPlan()
      Description copied from interface: DNStateManager
      Refreshes from the database all fields in fetch plan. Called by life-cycle transitions when the object undergoes a "transitionRefresh".
      Specified by:
      refreshFieldsInFetchPlan in interface DNStateManager<Persistable>
    • refreshLoadedFields

      public void refreshLoadedFields()
      Description copied from interface: DNStateManager
      Refreshes from the database all fields currently loaded. Called by life-cycle transitions when making transactional or reading fields.
      Specified by:
      refreshLoadedFields in interface DNStateManager<Persistable>
    • isLoaded

      public boolean isLoaded(int fieldNumber)
      Description copied from interface: DNStateManager
      Returns the loaded setting for the field of the managed object. Refer to the javadoc of isLoaded(Persistable, int);
      Specified by:
      isLoaded in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - the absolute field number
      Returns:
      always returns true (this implementation)
    • isLoaded

      public boolean isLoaded(Persistable pc, int fieldNumber)
      Return true if the field is cached in the calling instance; in this implementation we always return true. If the field is not loaded, it will be loaded as a side effect of the call to this method. If it is in the default fetch group, the default fetch group, including this field, will be loaded.
      Specified by:
      isLoaded in interface StateManager
      Parameters:
      pc - the calling Persistable instance
      fieldNumber - the absolute field number
      Returns:
      always returns true (this implementation)
    • replaceFieldValue

      public void replaceFieldValue(int fieldNumber, Object newValue)
      Convenience method to change the value of a field that is assumed loaded. Will mark the object/field as dirty if it isn't previously. If the object is deleted then does nothing. Doesn't cater for embedded fields. *** Only for use in management of relations. ***
      Specified by:
      replaceFieldValue in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Number of field
      newValue - The new value
    • replaceField

      public void replaceField(int fieldNumber, Object value)
      Method to change the value of a particular field and not mark it dirty.
      Specified by:
      replaceField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Number of field
      value - New value
    • replaceFieldMakeDirty

      public void replaceFieldMakeDirty(int fieldNumber, Object value)
      Method to change the value of a particular field and mark it dirty.
      Specified by:
      replaceFieldMakeDirty in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - Number of field
      value - New value
    • replaceField

      protected void replaceField(Persistable pc, int fieldNumber, Object value, boolean makeDirty)
      Method to change the value of a field in the PC object. Adds on handling for embedded fields to the superclass handler.
      Parameters:
      pc - The PC object
      fieldNumber - Number of field
      value - The new value of the field
      makeDirty - Whether to make the field dirty while replacing its value (in embedded owners)
    • replaceFields

      public void replaceFields(int[] fieldNumbers, FieldManager fm, boolean replaceWhenDirty)
      Called from the StoreManager to refresh data in the Persistable object associated with this StateManager. Typically called as a result of a query, so as to populate the query results into the associated persistable object(s).
      Specified by:
      replaceFields in interface DNStateManager<Persistable>
      Parameters:
      fieldNumbers - Field numbers to be refreshed from the store data
      fm - The updated values are stored in this object. This object is only valid for the duration of this call.
      replaceWhenDirty - Whether to replace the fields when they are dirty here
    • replaceFields

      public void replaceFields(int[] fieldNumbers, FieldManager fm)
      Called from the StoreManager to refresh data in the Persistable object associated with this StateManager.
      Specified by:
      replaceFields in interface DNStateManager<Persistable>
      Parameters:
      fieldNumbers - An array of field numbers to be refreshed by the Store
      fm - The updated values are stored in this object. This object is only valid for the duration of this call.
    • replaceNonLoadedFields

      public void replaceNonLoadedFields(int[] fieldNumbers, FieldManager fm)
      Called from the StoreManager to refresh data in the Persistable object associated with this StateManager. Only fields that are not currently loaded are refreshed
      Specified by:
      replaceNonLoadedFields in interface DNStateManager<Persistable>
      Parameters:
      fieldNumbers - An array of field numbers to be refreshed by the Store
      fm - The updated values are stored in this object. This object is only valid for the duration of this call.
    • replaceAllLoadedSCOFieldsWithWrappers

      public void replaceAllLoadedSCOFieldsWithWrappers()
      Method to replace all loaded SCO fields with wrappers. If the loaded field already uses a SCO wrapper nothing happens to that field.
      Specified by:
      replaceAllLoadedSCOFieldsWithWrappers in interface DNStateManager<Persistable>
    • replaceAllLoadedSCOFieldsWithValues

      public void replaceAllLoadedSCOFieldsWithValues()
      Method to replace all loaded SCO fields that have wrappers with their value. If the loaded field doesn't have a SCO wrapper nothing happens to that field.
      Specified by:
      replaceAllLoadedSCOFieldsWithValues in interface DNStateManager<Persistable>
    • updateOwnerFieldInEmbeddedField

      public void updateOwnerFieldInEmbeddedField(int fieldNumber, Object value)
      Method to update the "owner-field" in an embedded object with the owner object. TODO Likely this should be moved into a replaceField method, or maybe Managed Relationships.
      Specified by:
      updateOwnerFieldInEmbeddedField in interface DNStateManager<Persistable>
      Parameters:
      fieldNumber - The field number
      value - The value to initialise the wrapper with (if any)
    • makePersistent

      public void makePersistent()
      Method to make the object persistent.
      Specified by:
      makePersistent in interface DNStateManager<Persistable>
    • internalMakePersistent

      private void internalMakePersistent()
      Method to persist the object to the datastore.
    • makeTransactional

      public void makeTransactional()
      Method to change the object state to transactional.
      Specified by:
      makeTransactional in interface DNStateManager<Persistable>
    • makeTransient

      public void makeTransient(FetchPlanState state)
      Method to change the object state to transient.
      Specified by:
      makeTransient in interface DNStateManager<Persistable>
      Parameters:
      state - Object containing the state of any fetchplan processing
    • makeTransientForReachability

      public void makeTransientForReachability()
      Make the managed object transient as a result of persistence-by-reachability when run at commit time. The object was brought into persistence by reachability but found to not be needed at commit time. Here we delete it from persistence (since it will have been persisted/flushed to the datastore), and then we migrate the lifecycle to transient (which disconnects this StateManager).
      Specified by:
      makeTransientForReachability in interface DNStateManager<Persistable>
    • detach

      public void detach(FetchPlanState state)
      Method to detach this object. If the object is detachable then it will be migrated to DETACHED state, otherwise will migrate to TRANSIENT. Used by "DetachAllOnCommit"/"DetachAllOnRollback"
      Specified by:
      detach in interface DNStateManager<Persistable>
      Parameters:
      state - State for the detachment process
    • detachCopy

      public Persistable detachCopy(FetchPlanState state)
      Method to make detached copy of this instance If the object is detachable then the copy will be migrated to DETACHED state, otherwise will migrate the copy to TRANSIENT. Used by "ExecutionContext.detachObjectCopy()".
      Specified by:
      detachCopy in interface DNStateManager<Persistable>
      Parameters:
      state - State for the detachment process
      Returns:
      the detached Persistable instance
    • setDetaching

      void setDetaching(boolean flag)
    • isDetaching

      public boolean isDetaching()
      Description copied from interface: DNStateManager
      Tests whether this object is in the process of being detached.
      Specified by:
      isDetaching in interface DNStateManager<Persistable>
      Returns:
      true if this instance is being detached.
    • getFieldsNumbersToDetach

      private int[] getFieldsNumbersToDetach()
      Return an array of field numbers that must be included in the detached object
      Returns:
      the field numbers array for detaching
    • attach

      public void attach(Persistable detachedPC)
      Description copied from interface: DNStateManager
      Method to attach the provided detached object into the managed instance.
      Specified by:
      attach in interface DNStateManager<Persistable>
      Parameters:
      detachedPC - Detached object
    • attach

      public void attach(boolean embedded)
      Method to attach the object managed by this StateManager.
      Specified by:
      attach in interface DNStateManager<Persistable>
      Parameters:
      embedded - Whether it is embedded
    • attachCopy

      public Persistable attachCopy(Persistable detachedPC, boolean embedded)
      Method to attach a copy of the detached persistable instance and return the (attached) copy.
      Specified by:
      attachCopy in interface DNStateManager<Persistable>
      Parameters:
      detachedPC - the detached persistable instance to be attached
      embedded - Whether the object is stored embedded/serialised in another object
      Returns:
      The attached copy
    • setAttaching

      void setAttaching(boolean flag)
    • isAttaching

      public boolean isAttaching()
    • internalAttachCopy

      private void internalAttachCopy(DNStateManager detachedSM, boolean[] loadedFields, boolean[] dirtyFields, boolean persistent, Object version, boolean cascade)
      Attach the fields for this object using the provided detached object. This will attach all loaded plus all dirty fields.
      Parameters:
      detachedSM - StateManager for the detached object.
      loadedFields - Fields that were detached with the object
      dirtyFields - Fields that have been modified while detached
      persistent - whether the object is already persistent
      version - the version
      cascade - Whether to cascade the attach to related fields
    • deletePersistent

      public void deletePersistent()
      Method to delete the object from persistence.
      Specified by:
      deletePersistent in interface DNStateManager<Persistable>
    • becomingDeleted

      public boolean becomingDeleted()
      Description copied from interface: DNStateManager
      Whether this object is moving to a deleted state.
      Specified by:
      becomingDeleted in interface DNStateManager<Persistable>
      Returns:
      Whether the object will be moved into a deleted state during this operation
    • validate

      public void validate()
      Validates whether the persistable instance exists in the datastore. If the instance doesn't exist in the datastore, this method will fail raising a NucleusObjectNotFoundException. If the object is transactional then does nothing. If the object has unloaded (non-SCO, non-PK) fetch plan fields then fetches them. Else it checks the existence of the object in the datastore.
      Specified by:
      validate in interface DNStateManager<Persistable>
    • preWriteField

      protected boolean preWriteField(int fieldNumber)
      Method called before a write of the specified field.
      Parameters:
      fieldNumber - The field to write
      Returns:
      true if the field was already dirty before
    • postWriteField

      protected void postWriteField(boolean wasDirty)
      Method called after the write of a field.
      Parameters:
      wasDirty - whether before writing this field the pc was dirty
    • preStateChange

      protected void preStateChange()
      Method called before a change in state.
    • postStateChange

      protected void postStateChange()
      Method called after a change in state.
    • setPostLoadPending

      void setPostLoadPending(boolean flag)
    • isPostLoadPending

      protected boolean isPostLoadPending()
    • postLoad

      private void postLoad()
      Called whenever the default fetch group fields have all been loaded. Updates dnFlags and calls dnPostLoad() as appropriate.

      If it's called in the midst of a life-cycle transition both actions will be deferred until the transition is complete. This deferral is important. Without it, we could enter user code (dnPostLoad()) while still making a state transition, and that way lies madness.

      As an example, consider a dnPostLoad() that calls other enhanced methods that read fields (dnPostLoad() itself is not enhanced). A P_NONTRANS object accessed within a transaction would produce the following infinite loop:

        isLoaded()
        transitionReadField()
        refreshLoadedFields()
        dnPostLoad()
        isLoaded()
        ...
       

      because the transition from P_NONTRANS to P_CLEAN can never be completed.

    • preSerialize

      public void preSerialize(Persistable pc)
      Guarantee that the serializable transactional and persistent fields are loaded into the instance. This method is called by the generated dnPreSerialize method prior to serialization of the instance.
      Specified by:
      preSerialize in interface StateManager
      Parameters:
      pc - the calling Persistable instance
    • setStoringPC

      public void setStoringPC()
      Description copied from interface: DNStateManager
      Method to set the storing PC flag.
      Specified by:
      setStoringPC in interface DNStateManager<Persistable>
    • unsetStoringPC

      public void unsetStoringPC()
      Description copied from interface: DNStateManager
      Method to unset the storing PC flag.
      Specified by:
      unsetStoringPC in interface DNStateManager<Persistable>
    • isStoringPC

      protected boolean isStoringPC()
    • flush

      public void flush()
      Flushes any outstanding changes to the object to the datastore. This will process :-
      • Any objects that have been marked as provisionally persistent yet haven't been flushed to the datastore.
      • Any objects that have been marked as provisionally deleted yet haven't been flushed to the datastore.
      • Any fields that have been updated.
      Specified by:
      flush in interface DNStateManager<Persistable>
    • saveFields

      public void saveFields()
      Method to save all fields of the object, for use in any rollback.
      Specified by:
      saveFields in interface DNStateManager<Persistable>
    • restoreFields

      public void restoreFields()
      Method to restore all fields of the object.
      Specified by:
      restoreFields in interface DNStateManager<Persistable>
    • clearSavedFields

      public void clearSavedFields()
      Method to clear all saved fields on the object.
      Specified by:
      clearSavedFields in interface DNStateManager<Persistable>
    • convertPCToString

      private static String convertPCToString(Object pc, AbstractClassMetaData cmd)
      Method to convert the persistable object into String form.
      Parameters:
      pc - The persistable object
      cmd - Metadata for the class
      Returns:
      The string containing the description of the Persistable
    • log

      public void log(NucleusLogger log)
      Utility to dump the contents of the StateManager to the provided log.
      Parameters:
      log - Logger to use
    • peekField

      protected static Object peekField(Object obj, String fieldName)
      Utility to take a peek at a field in the persistable object.
      Parameters:
      obj - The persistable object
      fieldName - The field to peek at
      Returns:
      The value of the field.
    • updateFieldAfterInsert

      public void updateFieldAfterInsert(Object pc, int fieldNumber)
      Description copied from interface: DNStateManager
      Marks the given field dirty for issuing an update after the insert.
      Specified by:
      updateFieldAfterInsert in interface DNStateManager<Persistable>
      Parameters:
      pc - The Persistable object
      fieldNumber - The no of field to mark as dirty.
    • initialiseForHollowAppId

      public void initialiseForHollowAppId(FieldValues fv, Class pcClass)
      Deprecated.
      Remove use of this and use initialiseForHollow
      Initialises a state manager to manage a HOLLOW / P_CLEAN instance having the given FieldValues. This constructor is used for creating new instances of existing persistent objects using application identity, and consequently shouldn't be used when the StoreManager controls the creation of such objects (such as in an ODBMS).
      Specified by:
      initialiseForHollowAppId in interface DNStateManager<Persistable>
      Parameters:
      fv - the initial field values of the object.
      pcClass - Class of the object that this will manage the state for
    • checkInheritance

      public void checkInheritance(FieldValues fv)
      Deprecated.
      Dont use this, to be removed
      Look to the database to determine which class this object is. This parameter is a hint. Set false, if it's already determined the correct pcClass for this pc "object" in a certain level in the hierarchy. Set to true and it will look to the database. TODO This is only called by some outdated code in LDAPUtils; remove it when that is fixed
      Specified by:
      checkInheritance in interface DNStateManager<Persistable>
      Parameters:
      fv - the initial field values of the object.