blob: c98a4e81272f9bd03570ed1a3f055f70d526b89c [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// tware - initial API check-in for MappedKeyMapContainerPolicy
package org.eclipse.persistence.mappings.foundation;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;
/**
* MapKeyMapping is implemented by DatabaseMappings that can be used to map the key in a map
* that uses a MappedKeyMapContainerPolicy. This interface provides the facilities to retreive data
* for the key from the database, to get data from the object to put in the database, and to appropriately
* initialize the mappings.
*
* @see MappedKeyMapContainerPolicy
* @see AbstractDirectMapping
* @see org.eclipse.persistence.mappings.AggregateObjectMapping
* @see org.eclipse.persistence.mappings.OneToOneMapping
* @author tware
*
*/
public interface MapKeyMapping extends MapComponentMapping {
/**
* INTERNAL:
* Used when initializing queries for mappings that use a Map
* Called when the selection query is being initialized to add the fields for the map key to the query
*/
void addAdditionalFieldsToQuery(ReadQuery selectionQuery, Expression baseExpression);
/**
* INTERNAL:
* Used when initializing queries for mappings that use a Map
* Called when the insert query is being initialized to ensure the fields for the map key are in the insert query
*/
void addFieldsForMapKey(AbstractRecord joinRow);
/**
* INTERNAL:
* For mappings used as MapKeys in MappedKeyContainerPolicy. Add the target of this mapping to the deleted
* objects list if necessary
*
* This method is used for removal of private owned relationships
*
*/
void addKeyToDeletedObjectsList(Object object, Map deletedObjects);
/**
* Build a clone of the given element in a unitOfWork
*/
Object buildElementClone(Object element, Object parent, CacheKey cacheKey, Integer refreshCascade, AbstractSession cloningSession, boolean isExisting, boolean isFromSharedCache);
/**
* INTERNAL:
* Depending on the MapKeyMapping, a different selection query may be required to retrieve the
* map when the map is based on a DirectCollectionMapping
*/
ReadQuery buildSelectionQueryForDirectCollectionKeyMapping(ContainerPolicy containerPolicy);
/**
* INTERNAL:
* Cascade discover and persist new objects during commit to the map key
*/
void cascadeDiscoverAndPersistUnregisteredNewObjects(Object object, Map newObjects, Map unregisteredExistingObjects, Map visitedObjects, UnitOfWorkImpl uow, boolean getAttributeValueFromObject, Set cascadeErrors);
/**
* INTERNAL:
* Cascade perform delete through mappings that require the cascade
*/
void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects, boolean getAttributeValueFromObject);
/**
* INTERNAL:
* Cascade registerNew for Create through mappings that require the cascade
*/
void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects, boolean getAttributeValueFromObject);
/**
* INTERNAL
* Called when a DatabaseMapping is used to map the key in a collection and a join query is used.
* Returns the key.
*/
Object createMapComponentFromJoinedRow(AbstractRecord dbRow, JoinedAttributeManager joinManager, ObjectBuildingQuery query, CacheKey parentCacheKey, AbstractSession session, boolean isTargetProtected);
/**
* INTERNAL:
* Create a query key that links to the map key
*/
QueryKey createQueryKeyForMapKey();
/**
* INTERNAL:
* Creates the Array of simple types used to recreate this map.
*/
Object createSerializableMapKeyInfo(Object key, AbstractSession session);
/**
* INTERNAL:
* Create an instance of the Key object from the key information extracted from the map.
* This may return the value directly in case of a simple key or will be used as the FK to load a related entity.
*/
List<Object> createMapComponentsFromSerializableKeyInfo(Object[] keyInfo, AbstractSession session);
/**
* INTERNAL:
* Create an instance of the Key object from the key information extracted from the map.
* This key object may be a shallow stub of the actual object if the key is an Entity type.
*/
Object createStubbedMapComponentFromSerializableKeyInfo(Object keyInfo, AbstractSession session);
/**
* INTERNAL:
* For mappings used as MapKeys in MappedKeyContainerPolicy, Delete the passed object if necessary.
*
* This method is used for removal of private owned relationships
*
*/
void deleteMapKey(Object objectDeleted, AbstractSession session);
/**
* INTERNAL:
* Return any tables that will be required when this mapping is used as part of a join query
*/
List<DatabaseTable> getAdditionalTablesForJoinQuery();
/**
* INTERNAL:
* Get all the fields for the map key
*/
List<DatabaseField> getAllFieldsForMapKey();
/**
* INTERNAL:
* Return a Map of any foreign keys defined within the the MapKey
*/
Map<DatabaseField, DatabaseField> getForeignKeyFieldsForMapKey();
/**
* INTERNAL:
* Get the descriptor for the Map Key
*/
ClassDescriptor getReferenceDescriptor();
/**
* INTERNAL:
* Return the fields that make up the identity of the mapped object. For mappings with
* a primary key, it will be the set of fields in the primary key. For mappings without
* a primary key it will likely be all the fields
*/
List<DatabaseField> getIdentityFieldsForMapKey();
/**
* INTERNAL:
* Return the query that is used when this mapping is part of a joined relationship
*/
ObjectLevelReadQuery getNestedJoinQuery(JoinedAttributeManager joinManager, ObjectLevelReadQuery query, AbstractSession session);
/**
* INTERNAL:
* Return the selection criteria necessary to select the target object
*/
Expression getAdditionalSelectionCriteriaForMapKey();
/**
* INTERNAL:
* If required, get the targetVersion of the source object from the merge manager
*/
Object getTargetVersionOfSourceObject(Object object, Object parent, MergeManager mergeManager, AbstractSession targetSession);
/**
* INTERNAL:
* Return the class this key mapping maps or the descriptor for it
*/
Object getMapKeyTargetType();
/**
* INTERNAL:
* Called when iterating through descriptors to handle iteration on this mapping when it is used as a MapKey
*/
void iterateOnMapKey(DescriptorIterator iterator, Object element);
/**
* INTERNAL:
* Extract the fields for the Map key from the object to use in a query
*/
Map extractIdentityFieldsForQuery(Object key, AbstractSession session);
/**
* INTERNAL:
* Making any mapping changes necessary to use a the mapping as a map key prior to initializing the mapping
*/
void preinitializeMapKey(DatabaseTable table) throws DescriptorException;
/**
* INTERNAL:
* Making any mapping changes necessary to use a the mapping as a map key after initializing the mapping
*/
void postInitializeMapKey(MappedKeyMapContainerPolicy policy) throws DescriptorException;
/**
* INTERNAL:
* Return whether this mapping requires extra queries to update the rows if it is
* used as a key in a map. This will typically be true if there are any parts to this mapping
* that are not read-only.
*/
boolean requiresDataModificationEventsForMapKey();
/**
* INTERNAL:
* Allow the key mapping to unwrap the object
*/
Object unwrapKey(Object key, AbstractSession session);
/**
* INTERNAL:
* Allow the key mapping to wrap the object
*/
Object wrapKey(Object key, AbstractSession session);
}