Class OneToManyMapping

All Implemented Interfaces:
Serializable, Cloneable, ContainerMapping, MapComponentMapping, RelationalMapping
Direct Known Subclasses:
UnidirectionalOneToManyMapping

public class OneToManyMapping extends CollectionMapping implements RelationalMapping, MapComponentMapping

Purpose: This mapping is used to represent the typical RDBMS relationship between a single source object and collection of target objects; where, on the database, the target objects have references (foreign keys) to the source object.

Since:
TOPLink/Java 1.0
See Also:
  • Field Details

    • PostInsert

      protected static final String PostInsert
      Used for data modification events.
      See Also:
    • ObjectRemoved

      protected static final String ObjectRemoved
      See Also:
    • ObjectAdded

      protected static final String ObjectAdded
      See Also:
    • targetForeignKeyFields

      protected Vector<DatabaseField> targetForeignKeyFields
      The target foreign key fields that reference the sourceKeyFields.
    • sourceKeyFields

      protected Vector<DatabaseField> sourceKeyFields
      The (typically primary) source key fields that are referenced by the targetForeignKeyFields.
    • targetForeignKeysToSourceKeys

      protected transient Map<DatabaseField,DatabaseField> targetForeignKeysToSourceKeys
      This maps the target foreign key fields to the corresponding (primary) source key fields.
    • sourceKeysToTargetForeignKeys

      protected transient Map<DatabaseField,DatabaseField> sourceKeysToTargetForeignKeys
      This maps the (primary) source key fields to the corresponding target foreign key fields.
    • targetForeignKeyTable

      protected transient DatabaseTable targetForeignKeyTable
      All targetForeignKeyFields should have the same table. Used only in case data modification events required.
    • targetPrimaryKeyFields

      protected transient List<DatabaseField> targetPrimaryKeyFields
      Primary keys of targetForeignKeyTable: the same as referenceDescriptor().getPrimaryKeyFields() in case the table is default table of reference descriptor; otherwise contains secondary table's primary key fields in the same order as default table primary keys mapped to them. Used only in case data modification events required.
    • sourceExpressionsToPostInitialize

      protected transient List<Expression> sourceExpressionsToPostInitialize
      Keep a reference to the source and target expressions to post initialize when building a selection criteria early.
    • targetExpressionsToPostInitialize

      protected transient List<Expression> targetExpressionsToPostInitialize
    • addTargetQuery

      protected DataModifyQuery addTargetQuery
      Query used to update a single target row setting its foreign key to point to the source. Run once for each target added to the source. Example: for Employee with managedEmployees attribute mapped with UnidirectionalOneToMany the query looks like: UPDATE EMPLOYEE SET MANAGER_ID = 1 WHERE (EMP_ID = 2) where 1 is id of the source, and 2 is the id of the target to be added. Used only in case data modification events required.
    • hasCustomAddTargetQuery

      protected boolean hasCustomAddTargetQuery
    • shouldDeferInserts

      protected Boolean shouldDeferInserts
    • removeTargetQuery

      protected DataModifyQuery removeTargetQuery
      Query used to update a single target row changing its foreign key value from the one pointing to the source to null. Run once for each target removed from the source. Example: for Employee with managedEmployees attribute mapped with UnidirectionalOneToMany the query looks like: UPDATE EMPLOYEE SET MANAGER_ID = null WHERE ((MANAGER_ID = 1) AND (EMP_ID = 2)) where 1 is id of the source, and 2 is the id of the target to be removed. Used only in case data modification events required.
    • hasCustomRemoveTargetQuery

      protected boolean hasCustomRemoveTargetQuery
    • removeAllTargetsQuery

      protected DataModifyQuery removeAllTargetsQuery
      Query used to update all target rows changing target foreign key value from the one pointing to the source to null. Run before the source object is deleted. Example: for Employee with managedEmployees attribute mapped with UnidirectionalOneToMany the query looks like: UPDATE EMPLOYEE SET MANAGER_ID = null WHERE (MANAGER_ID = 1) where 1 is id of the source to be deleted. Used only in case data modification events required.
    • hasCustomRemoveAllTargetsQuery

      protected boolean hasCustomRemoveAllTargetsQuery
  • Constructor Details

    • OneToManyMapping

      public OneToManyMapping()
      PUBLIC: Default constructor.
  • Method Details

    • isRelationalMapping

      public boolean isRelationalMapping()
      INTERNAL:
      Overrides:
      isRelationalMapping in class DatabaseMapping
    • addTargetForeignKeyField

      public void addTargetForeignKeyField(DatabaseField targetForeignKeyField, DatabaseField sourceKeyField)
      INTERNAL: Add the associated fields to the appropriate collections.
      Overrides:
      addTargetForeignKeyField in class ForeignReferenceMapping
    • addTargetForeignKeyFieldName

      public void addTargetForeignKeyFieldName(String targetForeignKeyFieldName, String sourceKeyFieldName)
      PUBLIC: Define the target foreign key relationship in the one-to-many mapping. This method is used for composite target foreign key relationships. That is, the target object's table has multiple foreign key fields that are references to the source object's (typically primary) key fields. Both the target foreign key field name and the corresponding source primary key field name must be specified. Because the target object's table must store a foreign key to the source table, the target object must map that foreign key, this is normally done through a one-to-one mapping back-reference. Other options include:
      • use a DirectToFieldMapping and maintain the foreign key fields directly in the target
      • use a ManyToManyMapping
      • use an AggregateCollectionMapping
      See Also:
    • buildListOrderField

      protected void buildListOrderField()
      INTERNAL: Verifies listOrderField's table: it must be the same table that contains all target foreign keys. Precondition: listOrderField != null.
      Overrides:
      buildListOrderField in class CollectionMapping
    • buildDefaultSelectionCriteriaAndAddFieldsToQuery

      protected Expression buildDefaultSelectionCriteriaAndAddFieldsToQuery()
      The selection criteria are created with target foreign keys and source "primary" keys. These criteria are then used to read the target records from the table. These criteria are also used as the default "delete all" criteria. CR#3922 - This method is almost the same as buildSelectionCriteria() the difference is that TargetForeignKeysToSourceKeys contains more information after login then SourceKeyFields contains before login.
    • buildSelectionCriteria

      public Expression buildSelectionCriteria()
      This method would allow customers to get the potential selection criteria for a mapping prior to initialization. This would allow them to more easily create an amendment method that would amend the SQL for the join. CR#3922 - This method is almost the same as buildDefaultSelectionCriteria() the difference is that TargetForeignKeysToSourceKeys contains more information after login then SourceKeyFields contains before login.
    • collectQueryParameters

      public void collectQueryParameters(Set<DatabaseField> cacheFields)
      INTERNAL: This method is used to store the FK fields that can be cached that correspond to noncacheable mappings the FK field values will be used to re-issue the query when cloning the shared cache entity
      Overrides:
      collectQueryParameters in class CollectionMapping
      Parameters:
      cacheFields - TODO
    • clone

      public Object clone()
      INTERNAL: Clone the appropriate attributes.
      Specified by:
      clone in interface MapComponentMapping
      Overrides:
      clone in class CollectionMapping
      Returns:
      new instance of itself
    • createMapComponentFromRow

      public Object createMapComponentFromRow(AbstractRecord dbRow, ObjectBuildingQuery query, CacheKey parentCacheKey, AbstractSession session, boolean isTargetProtected)
      INTERNAL Called when a DatabaseMapping is used to map the key in a collection. Returns the key.
      Specified by:
      createMapComponentFromRow in interface MapComponentMapping
    • deleteAll

      protected void deleteAll(DeleteObjectQuery query, AbstractSession session) throws DatabaseException
      Delete all the reference objects with a single query.
      Throws:
      DatabaseException
    • deleteReferenceObjectsLeftOnDatabase

      protected void deleteReferenceObjectsLeftOnDatabase(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException
      This method will make sure that all the records privately owned by this mapping are actually removed. If such records are found then those are all read and removed one by one along with their privately owned parts.
      Throws:
      DatabaseException
      OptimisticLockException
    • extractKeyFromTargetRow

      protected Object extractKeyFromTargetRow(AbstractRecord row, AbstractSession session)
      INTERNAL: Extract the source primary key value from the target row. Used for batch reading, most following same order and fields as in the mapping.
      Overrides:
      extractKeyFromTargetRow in class CollectionMapping
    • extractBatchKeyFromRow

      protected Object extractBatchKeyFromRow(AbstractRecord row, AbstractSession session)
      Extract the key field values from the specified row. Used for batch reading. Keep the fields in the same order as in the targetForeignKeysToSourceKeys map.
      Overrides:
      extractBatchKeyFromRow in class ForeignReferenceMapping
    • getDeleteAllQuery

      protected ModifyQuery getDeleteAllQuery()
      Overrides CollectionMappig because this mapping requires a DeleteAllQuery instead of a ModifyQuery.
      Overrides:
      getDeleteAllQuery in class CollectionMapping
    • getFieldsForTranslationInAggregate

      public Collection getFieldsForTranslationInAggregate()
      INTERNAL: Return source key fields for translation by an AggregateObjectMapping
      Overrides:
      getFieldsForTranslationInAggregate in class ForeignReferenceMapping
    • getSourceKeyFieldNames

      public Vector getSourceKeyFieldNames()
      PUBLIC: Return the source key field names associated with the mapping. These are in-order with the targetForeignKeyFieldNames.
    • getSourceKeyFields

      public Vector<DatabaseField> getSourceKeyFields()
      INTERNAL: Return the source key fields.
    • getSourceKeysToTargetForeignKeys

      public Map<DatabaseField,DatabaseField> getSourceKeysToTargetForeignKeys()
      INTERNAL: Return the source/target key fields.
    • getTargetPrimaryKeyFields

      public List<DatabaseField> getTargetPrimaryKeyFields()
      INTERNAL: Primary keys of targetForeignKeyTable.
      Overrides:
      getTargetPrimaryKeyFields in class CollectionMapping
    • getTargetForeignKeyFieldNames

      public Vector getTargetForeignKeyFieldNames()
      INTERNAL: Return the target foreign key field names associated with the mapping. These are in-order with the targetForeignKeyFieldNames.
    • getTargetForeignKeyFields

      public Vector<DatabaseField> getTargetForeignKeyFields()
      INTERNAL: Return the target foreign key fields.
    • getTargetForeignKeysToSourceKeys

      public Map<DatabaseField,DatabaseField> getTargetForeignKeysToSourceKeys()
      INTERNAL: Return the target/source key fields.
    • hasInverseConstraintDependency

      public boolean hasInverseConstraintDependency()
      INTERNAL: Return whether the mapping has any inverse constraint dependencies, such as foreign keys and join tables.
      Overrides:
      hasInverseConstraintDependency in class DatabaseMapping
    • initialize

      public void initialize(AbstractSession session) throws DescriptorException
      INTERNAL: Initialize the mapping.
      Overrides:
      initialize in class CollectionMapping
      Throws:
      DescriptorException
    • initializeAddTargetQuery

      protected void initializeAddTargetQuery(AbstractSession session)
      INTERNAL: Initialize addTargetQuery.
    • createModifyRowForAddTargetQuery

      protected AbstractRecord createModifyRowForAddTargetQuery()
      INTERNAL:
    • initializeChangeOrderTargetQuery

      protected void initializeChangeOrderTargetQuery(AbstractSession session)
      INTERNAL: Initialize changeOrderTargetQuery.
      Overrides:
      initializeChangeOrderTargetQuery in class CollectionMapping
    • initializeDeleteAllQuery

      protected void initializeDeleteAllQuery(AbstractSession session)
      Initialize the delete all query. This query is used to delete the collection of objects from the database.
    • initializeTargetPrimaryKeyFields

      protected void initializeTargetPrimaryKeyFields()
      INTERNAL: Initialize targetForeignKeyTable and initializeTargetPrimaryKeyFields. This method should be called after initializeTargetForeignKeysToSourceKeys method, which creates targetForeignKeyFields (guaranteed to be not empty in case requiresDataModificationEvents method returns true - the only case for the method to be called).
    • initializeRemoveTargetQuery

      protected void initializeRemoveTargetQuery(AbstractSession session)
      INTERNAL: Initialize removeTargetQuery.
    • initializeReferenceDescriptor

      protected void initializeReferenceDescriptor(AbstractSession session) throws DescriptorException
      Initialize and set the descriptor for the referenced class in this mapping. Added here initialization of target foreign keys and target primary keys so that they are ready when CollectionMapping.initialize initializes listOrderField.
      Overrides:
      initializeReferenceDescriptor in class ForeignReferenceMapping
      Throws:
      DescriptorException
    • initializeRemoveAllTargetsQuery

      protected void initializeRemoveAllTargetsQuery(AbstractSession session)
      INTERNAL: Initialize removeAllTargetsQuery.
    • initializeTargetForeignKeysToSourceKeys

      protected void initializeTargetForeignKeysToSourceKeys() throws DescriptorException
      Verify, munge, and hash the target foreign keys and source keys.
      Throws:
      DescriptorException
    • isOneToManyMapping

      public boolean isOneToManyMapping()
      INTERNAL:
      Overrides:
      isOneToManyMapping in class DatabaseMapping
    • isSourceKeySpecified

      protected boolean isSourceKeySpecified()
      Return whether the source key is specified. It will be empty when #setTargetForeignKeyFieldName(String) is used.
    • objectAddedDuringUpdate

      protected void objectAddedDuringUpdate(ObjectLevelModifyQuery query, Object objectAdded, ObjectChangeSet changeSet, Map extraData) throws DatabaseException, OptimisticLockException
      INTERNAL: An object was added to the collection during an update, insert it if private.
      Overrides:
      objectAddedDuringUpdate in class CollectionMapping
      Throws:
      DatabaseException
      OptimisticLockException
    • objectRemovedDuringUpdate

      protected void objectRemovedDuringUpdate(ObjectLevelModifyQuery query, Object objectDeleted, Map extraData) throws DatabaseException, OptimisticLockException
      INTERNAL: An object was removed to the collection during an update, delete it if private.
      Overrides:
      objectRemovedDuringUpdate in class CollectionMapping
      Throws:
      DatabaseException
      OptimisticLockException
    • performDataModificationEvent

      public void performDataModificationEvent(Object[] event, AbstractSession session) throws DatabaseException, DescriptorException
      INTERNAL: Perform the commit event. This is used in the uow to delay data modifications.
      Overrides:
      performDataModificationEvent in class DatabaseMapping
      Throws:
      DatabaseException
      DescriptorException
    • postInsert

      public void postInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException
      INTERNAL: Insert the reference objects.
      Overrides:
      postInsert in class CollectionMapping
      Throws:
      DatabaseException
      OptimisticLockException
    • postInitializeSourceAndTargetExpressions

      public void postInitializeSourceAndTargetExpressions()
      INTERNAL: Post-initialize source and target expression fields created when a mapping's selectionCriteria is created early with only partly initialized fields.
      Overrides:
      postInitializeSourceAndTargetExpressions in class DatabaseMapping
      See Also:
    • postUpdate

      public void postUpdate(WriteObjectQuery query) throws DatabaseException, OptimisticLockException
      INTERNAL: Update the reference objects.
      Overrides:
      postUpdate in class DatabaseMapping
      Throws:
      DatabaseException
      OptimisticLockException
    • buildBatchCriteria

      protected Expression buildBatchCriteria(ExpressionBuilder builder, ObjectLevelReadQuery query)
      INTERNAL: Return the selection criteria used to IN batch fetching.
      Overrides:
      buildBatchCriteria in class ForeignReferenceMapping
    • preDelete

      public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException
      INTERNAL: Delete the reference objects.
      Overrides:
      preDelete in class DatabaseMapping
      Throws:
      DatabaseException
      OptimisticLockException
    • prepareCascadeLockingPolicy

      public void prepareCascadeLockingPolicy()
      Prepare a cascade locking policy.
      Overrides:
      prepareCascadeLockingPolicy in class DatabaseMapping
    • requiresDataModificationEvents

      public boolean requiresDataModificationEvents()
      INTERNAL: Returns whether this mapping uses data modification events to complete its writes
      See Also:
    • setCustomAddTargetQuery

      public void setCustomAddTargetQuery(DataModifyQuery query)
      PUBLIC: The default add target query for mapping can be overridden by specifying the new query. This query must set new value to target foreign key.
    • setAddTargetSQLString

      public void setAddTargetSQLString(String sqlString)
      PUBLIC:
    • setCustomRemoveTargetQuery

      public void setCustomRemoveTargetQuery(DataModifyQuery query)
      PUBLIC: The default remove target query for mapping can be overridden by specifying the new query. In case target foreign key references the source, this query must set target foreign key to null.
    • setCustomRemoveAllTargetsQuery

      public void setCustomRemoveAllTargetsQuery(DataModifyQuery query)
      PUBLIC: The default remove all targets query for mapping can be overridden by specifying the new query. This query must set all target foreign keys that reference the source to null.
    • setDeleteAllSQLString

      public void setDeleteAllSQLString(String sqlString)
      PUBLIC: Set the SQL string used by the mapping to delete the target objects. This allows the developer to override the SQL generated by TopLink with a custom SQL statement or procedure call. The arguments are translated from the fields of the source row, by replacing the field names marked by '#' with the values for those fields at execution time. A one-to-many mapping will only use this delete all optimization if the target objects can be deleted in a single SQL call. This is possible when the target objects are in a single table, do not using locking, do not contain other privately-owned parts, do not read subclasses, etc.

      Example: "delete from PHONE where OWNER_ID = #EMPLOYEE_ID"

      Overrides:
      setDeleteAllSQLString in class CollectionMapping
    • setSessionName

      public void setSessionName(String name)
      PUBLIC: Set the name of the session to execute the mapping's queries under. This can be used by the session broker to override the default session to be used for the target class.
      Overrides:
      setSessionName in class CollectionMapping
    • setSourceKeyFieldNames

      public void setSourceKeyFieldNames(Vector fieldNames)
      INTERNAL: Set the source key field names associated with the mapping. These must be in-order with the targetForeignKeyFieldNames.
    • setSourceKeyFields

      public void setSourceKeyFields(Vector<DatabaseField> sourceKeyFields)
      INTERNAL: Set the source key fields.
    • setTargetForeignKeyFieldName

      public void setTargetForeignKeyFieldName(String targetForeignKeyFieldName)
      PUBLIC: Define the target foreign key relationship in the one-to-many mapping. This method can be used when the foreign and primary keys have only a single field each. (Use #addTargetForeignKeyFieldName(String, String) for "composite" keys.) Only the target foreign key field name is specified and the source (primary) key field is assumed to be the primary key of the source object. Because the target object's table must store a foreign key to the source table, the target object must map that foreign key, this is normally done through a one-to-one mapping back-reference. Other options include:
      • use a DirectToFieldMapping and maintain the foreign key fields directly in the target
      • use a ManyToManyMapping
      • use an AggregateCollectionMapping
      See Also:
    • setTargetForeignKeyFieldNames

      public void setTargetForeignKeyFieldNames(String[] targetForeignKeyFieldNames, String[] sourceKeyFieldNames)
      PUBLIC: Define the target foreign key relationship in the one-to-many mapping. This method is used for composite target foreign key relationships. That is, the target object's table has multiple foreign key fields to the source object's (typically primary) key fields. Both the target foreign key field names and the corresponding source primary key field names must be specified.
    • setTargetForeignKeyFieldNames

      public void setTargetForeignKeyFieldNames(Vector fieldNames)
      INTERNAL: Set the target key field names associated with the mapping. These must be in-order with the sourceKeyFieldNames.
    • setTargetForeignKeyFields

      public void setTargetForeignKeyFields(Vector<DatabaseField> targetForeignKeyFields)
      INTERNAL: Set the target fields.
    • setTargetForeignKeysToSourceKeys

      protected void setTargetForeignKeysToSourceKeys(Map<DatabaseField,DatabaseField> targetForeignKeysToSourceKeys)
      INTERNAL: Set the target fields.
    • shouldObjectModifyCascadeToParts

      protected boolean shouldObjectModifyCascadeToParts(ObjectLevelModifyQuery query)
      Return whether any process leading to object modification should also affect its parts. Used by write, insert, update, and delete.
      Overrides:
      shouldObjectModifyCascadeToParts in class ForeignReferenceMapping
    • shouldRemoveTargetQueryModifyTargetForeignKey

      protected boolean shouldRemoveTargetQueryModifyTargetForeignKey()
      INTERNAL If it's not a map then target foreign key has been already modified (set to null).
    • isCascadedLockingSupported

      public boolean isCascadedLockingSupported()
      INTERNAL Return true if this mapping supports cascaded version optimistic locking.
      Overrides:
      isCascadedLockingSupported in class DatabaseMapping
    • isJoiningSupported

      public boolean isJoiningSupported()
      INTERNAL: Return if this mapping support joining.
      Overrides:
      isJoiningSupported in class ForeignReferenceMapping
    • updateTargetRowPostInsertSource

      public void updateTargetRowPostInsertSource(WriteObjectQuery query) throws DatabaseException
      INTERNAL: Update target foreign keys after a new source was inserted. This follows following steps.
      Throws:
      DatabaseException
    • buildKeyRowForTargetUpdate

      protected AbstractRecord buildKeyRowForTargetUpdate(ObjectLevelModifyQuery query)
    • updateTargetForeignKeyPostUpdateSource_ObjectAdded

      public void updateTargetForeignKeyPostUpdateSource_ObjectAdded(ObjectLevelModifyQuery query, Object objectAdded, Map extraData) throws DatabaseException
      INTERNAL: Update target foreign key after a target object was added to the source. This follows following steps.

      - Extract primary key and its value from the source object.

      - Extract target key and its value from the target object.

      - Construct an update statement with above fields and values for target table.

      - execute the statement.

      Throws:
      DatabaseException
    • updateTargetForeignKeyPostUpdateSource_ObjectRemoved

      public void updateTargetForeignKeyPostUpdateSource_ObjectRemoved(ObjectLevelModifyQuery query, Object objectRemoved) throws DatabaseException
      INTERNAL: Update target foreign key after a target object was removed from the source. This follows following steps.

      - Extract primary key and its value from the source object.

      - Extract target key and its value from the target object.

      - Construct an update statement with above fields and values for target table.

      - execute the statement.

      Throws:
      DatabaseException
    • updateTargetRowPreDeleteSource

      public void updateTargetRowPreDeleteSource(ObjectLevelModifyQuery query) throws DatabaseException
      INTERNAL: Update target foreign key after a target object was removed from the source. This follows following steps.

      - Extract primary key and its value from the source object.

      - Extract target key and its value from the target object.

      - Construct an update statement with above fields and values for target table.

      - execute the statement.

      Throws:
      DatabaseException
    • verifyDelete

      public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException
      INTERNAL: Used to verify whether the specified object is deleted or not.
      Overrides:
      verifyDelete in class CollectionMapping
      Throws:
      DatabaseException
    • shouldDeferInsert

      public boolean shouldDeferInsert()
    • setShouldDeferInsert

      public void setShouldDeferInsert(boolean defer)
    • getInsertObjectQuery

      protected InsertObjectQuery getInsertObjectQuery(AbstractSession session, ClassDescriptor desc)
      INTERNAL: Returns a clone of InsertObjectQuery from the ClassDescriptor's DescriptorQueryManager or a new one