/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     30/05/2012-2.4 Guy Pelletier
//       - 354678: Temp classloader is still being used during metadata processing
//     06/03/2013-2.5.1 Guy Pelletier
//       - 402380: 3 jpa21/advanced tests failed on server with
//         "java.lang.NoClassDefFoundError: org/eclipse/persistence/testing/models/jpa21/advanced/enums/Gender"
package org.eclipse.persistence.mappings;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.descriptors.ClassNameConversionRequired;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.expressions.ObjectExpression;
import org.eclipse.persistence.internal.expressions.QueryKeyExpression;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.IdentityHashSet;
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.indirection.DatabaseValueHolder;
import org.eclipse.persistence.internal.queries.AttributeItem;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.internal.sessions.remote.RemoteSessionController;
import org.eclipse.persistence.internal.sessions.remote.RemoteValueHolder;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.queries.DeleteObjectQuery;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelModifyQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.QueryByExamplePolicy;
import org.eclipse.persistence.queries.WriteObjectQuery;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * <p><b>Purpose</b>: Defines how an attribute of an object maps to and from the database
 *
 * <p><b>Responsibilities</b>:<ul>
 * <li> Define type of relationship (1:1/1:M/M:M/etc.)
 * <li> Define instance variable name and fields names required
 * <li> Define any additional properties (ownership, indirection, read only, etc.)
 * <li> Control building the value for the instance variable from the database row
 * <li> Control building the database fields from the object
 * <li> Control any pre/post updating/inserting/deleting required to maintain the relationship
 * <li> Merges object changes for unit of work.
 * <li> Clones objects for unit of work.
 * <li> cache computed information to optimize performance
 * </ul>
 *
 * @author Sati
 * @since TOPLink/Java 1.0
 */
public abstract class DatabaseMapping extends CoreMapping<AttributeAccessor, AbstractSession, ContainerPolicy, ClassDescriptor, DatabaseField> implements Cloneable, Serializable {
    public enum WriteType { INSERT, UPDATE, UNDEFINED }

    /** Used to reduce memory for mappings with no fields. */
    protected static final Vector<DatabaseField> NO_FIELDS = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(0);

    /** Used to share integer instance to reduce memory. */
    protected static final Integer NO_WEIGHT = Integer.MAX_VALUE;
    protected static final Integer WEIGHT_DIRECT = 1;
    protected static final Integer WEIGHT_TRANSFORM = 100;
    protected static final Integer WEIGHT_AGGREGATE = 200;
    protected static final Integer WEIGHT_TO_ONE = 400;

    /** ClassDescriptor to which this mapping belongs to */
    protected ClassDescriptor descriptor;

    /** Wrapper to store the reference objects. */
    protected AttributeAccessor attributeAccessor;

    /** Makes this mapping read only. No write are performed on it. Default is false */
    protected boolean isReadOnly;

    /** Specifies whether this mapping is optional (i.e. field may be null). Used for DDL generation. */
    protected boolean isOptional;

    /** Specifies whether this mapping is lazy, this means not included in the default fetch group. */
    protected Boolean isLazy;

    /** Fields associated with the mappings are cached */
    protected Vector<DatabaseField> fields;

    /** It is needed only in remote initialization and mapping is in parent descriptor */
    protected boolean isRemotelyInitialized;

    /** This is a TopLink defined attribute that allows us to sort the mappings */
    protected Integer weight = NO_WEIGHT;

    /** Allow user defined properties. */
    protected Map properties;
    /** Allow the user to defined un-converted properties which will be initialized at runtime. */
    protected Map<String, List<String>> unconvertedProperties;

    /**
     * Used by the CMP3Policy to see if this mapping should be used in
     * processing pk classes for find methods
     */
    protected boolean derivesId;

    /**
     *
     */
    protected boolean isJPAId = false;

    /**
     * A mapsId value.
     */
    protected String mapsIdValue;

    /**
     * The id mapping this mapping derives. Used by the CMP3Policy to see if
     * this mapping should be used in processing pk classes for find methods.
     */
    protected DatabaseMapping derivedIdMapping;

    /**
     * PERF: Used as a quick check to see if this mapping is a primary key mapping,
     * set by the object builder during initialization.
     */
    protected boolean isPrimaryKeyMapping = false;

    /**
     * PERF: Cache the mappings attribute name.
     */
    protected String attributeName;

    /**
     * Records if this mapping is being used as a MapKeyMapping.  This is important for recording main mappings
     */
    protected boolean isMapKeyMapping = false;

    //used by the object build/merge code to control building/merging into the
    //shared cache.
    protected boolean isCacheable = true;

    /**
     * Irrelevant (and not set) unless descriptor has SerializedObjectPolicy (SOP).
     * If descriptor has SOP, then ObjectLevelReadQuery (with shouldUseSerializedObjectPolicy flag set to true)
     * reads in row that contain both field/value pairs and sopObject.
     * This flag indicates whether the data for this mapping is contained in the row's sopObject or in fields/values.
     *   Boolean.TRUE - sopObject (in sopObject)
     *   Boolean.FALSE - fields/values (out sopObject);
     *   null -  both sopObject and fields/values (both in and out sopObject).
     * While writing to the data base the mapping will be used for writing into sopObject unless this flag is set to Boolean.FALSE;
     */
    protected Boolean isInSopObject;

    /**
     * PUBLIC:
     * Default constructor.
     */
    protected DatabaseMapping() {
        this.isOptional = true;
        this.isReadOnly = false;
        this.attributeAccessor = new InstanceVariableAttributeAccessor();
    }

    /**
     * PUBLIC:
     * Add an unconverted property (to be initialiazed at runtime)
     *
     * @param propertyName TODO
     * @param propertyValue TODO
     * @param propertyType TODO
     */
    public void addUnconvertedProperty(String propertyName, String propertyValue, String propertyType) {
        List<String> valuePair = new ArrayList<>(2);
        valuePair.add(propertyValue);
        valuePair.add(propertyType);
        getUnconvertedProperties().put(propertyName, valuePair);
    }

    /**
     * INTERNAL:
     * Clone the attribute from the clone and assign it to the backup.
     *
     * @param clone TODO
     * @param backup TODO
     * @param unitOfWork TODO
     */
    public abstract void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork);

    /**
     * INTERNAL:
     * Require for cloning, the part must be cloned.
     *
     * @param attributeValue TODO
     * @param clone TODO
     * @param backup TODO
     * @param unitOfWork TODO
     * @return TODO
     */
    public Object buildBackupCloneForPartObject(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        throw DescriptorException.invalidMappingOperation(this, "buildBackupCloneForPartObject");
    }

    /**
     * INTERNAL:
     * Clone the attribute from the original and assign it to the clone.
     *
     * @param original TODO
     * @param cacheKey TODO
     * @param clone TODO
     * @param refreshCascade TODO
     * @param cloningSession TODO
     */
    public abstract void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession);

    /**
     * INTERNAL:
     * A combination of readFromRowIntoObject and buildClone.
     * <p>
     * buildClone assumes the attribute value exists on the original and can
     * simply be copied.
     * <p>
     * readFromRowIntoObject assumes that one is building an original.
     * <p>
     * Both of the above assumptions are false in this method, and actually
     * attempts to do both at the same time.
     * <p>
     * Extract value from the row and set the attribute to this value in the
     * working copy clone.
     * In order to bypass the shared cache when in transaction a UnitOfWork must
     * be able to populate working copies directly from the row.
     *
     * @param databaseRow TODO
     * @param joinManager TODO
     * @param clone TODO
     * @param sharedCacheKey TODO
     * @param sourceQuery TODO
     * @param unitOfWork TODO
     * @param executionSession TODO
     */
    public abstract void buildCloneFromRow(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession);

    /**
     * INTERNAL:
     * Builds a shallow original object.  Only direct attributes and primary
     * keys are populated.  In this way the minimum original required for
     * instantiating a working copy clone can be built without placing it in
     * the shared cache (no concern over cycles).
     *
     * @param databaseRow TODO
     * @param original TODO
     * @param joinManager TODO
     * @param query TODO
     * @param executionSession TODO
     */
    public void buildShallowOriginalFromRow(AbstractRecord databaseRow, Object original, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession executionSession) {
        return;
    }

    /**
     * INTERNAL:
     * Require for cloning, the part must be cloned.
     * @param attributeValue TODO
     * @param original TODO
     * @param cacheKey TODO
     * @param clone TODO
     * @param cloningSession TODO
     * @param refreshCascade TODO
     * @param isExisting TODO
     * @param isFromSharedCache TODO
     * @return TODO
     */
    public Object buildCloneForPartObject(Object attributeValue, Object original, CacheKey cacheKey, Object clone, AbstractSession cloningSession, Integer refreshCascade, boolean isExisting, boolean isFromSharedCache) {
        throw DescriptorException.invalidMappingOperation(this, "buildCloneForPartObject");
    }

    /**
     * INTERNAL:
     * Performs a first level clone of the attribute.  This generally means on the container will be cloned.
     *
     * @param attributeValue TODO
     * @param cloningSession TODO
     * @return TODO
     */
    public Object buildContainerClone(Object attributeValue, AbstractSession cloningSession){
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Copy of the attribute of the object.
     * This is NOT used for unit of work but for templatizing an object.
     *
     * @param copy TODO
     * @param original TODO
     * @param group TODO
     */
    public void buildCopy(Object copy, Object original, CopyGroup group) {
    }

    /**
     * INTERNAL:
     * In case Query By Example is used, this method builds and returns an expression that
     * corresponds to a single attribue and it's value.
     *
     * @param queryObject TODO
     * @param policy TODO
     * @param expressionBuilder TODO
     * @param processedObjects TODO
     * @param session TODO
     * @return TODO
     */
    public Expression buildExpression(Object queryObject, QueryByExamplePolicy policy, Expression expressionBuilder, Map processedObjects, AbstractSession session) {
        if (policy.shouldValidateExample()){
            throw QueryException.unsupportedMappingQueryByExample(queryObject.getClass().getName(), this);
        }
        return null;
    }

    /**
     * INTERNAL:
     * Used to allow object level comparisons.
     *
     * @param base TODO
     * @param value TODO
     * @param session TODO
     * @return TODO
     */
    public Expression buildObjectJoinExpression(Expression base, Object value, AbstractSession session) {
        throw QueryException.unsupportedMappingForObjectComparison(this, base);
    }

    /**
     * INTERNAL:
     * Used to allow object level comparisons.
     *
     * @param base TODO
     * @param argument TODO
     * @param session TODO
     * @return TODO
     */
    public Expression buildObjectJoinExpression(Expression base, Expression argument, AbstractSession session) {
        throw QueryException.unsupportedMappingForObjectComparison(this, base);
    }

    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     *
     * @param object TODO
     * @param uow TODO
     * @param visitedObjects TODO
     */
    abstract public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects);

    /**
     * INTERNAL:
     * Cascade removal of orphaned private owned objects from the UnitOfWorkChangeSet
     *
     * @param object TODO
     * @param uow TODO
     * @param visitedObjects TODO
     */
    public void cascadePerformRemovePrivateOwnedObjectFromChangeSetIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        // no-op by default
    }

    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     *
     * @param object TODO
     * @param uow TODO
     * @param visitedObjects TODO
     */
    abstract public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects);

    /**
     * INTERNAL:
     * Cascade discover and persist new objects during commit.
     *
     * @param object TODO
     * @param newObjects TODO
     * @param unregisteredExistingObjects TODO
     * @param visitedObjects TODO
     * @param uow TODO
     * @param cascadeErrors TODO
     */
    public void cascadeDiscoverAndPersistUnregisteredNewObjects(Object object, Map newObjects, Map unregisteredExistingObjects, Map visitedObjects, UnitOfWorkImpl uow, Set cascadeErrors) {
        // Do nothing by default, (direct and xml mappings do not require anything).
    }

    /**
     * INTERNAL:
     * Used by AttributeLevelChangeTracking to update a changeRecord with calculated changes
     * as apposed to detected changes.  If an attribute can not be change tracked it's
     * changes can be detected through this process.
     *
     * @param changeRecord TODO
     * @param session TODO
     */
    public void calculateDeferredChanges(ChangeRecord changeRecord, AbstractSession session){
        throw DescriptorException.invalidMappingOperation(this, "calculatedDeferredChanges");
    }

    /**
     * INTERNAL:
     * Clones itself.
     *
     * @return new instance of itself
     */
    @Override
    public Object clone() {
        // Bug 3037701 - clone the AttributeAccessor
        DatabaseMapping mapping = null;
        try {
            mapping = (DatabaseMapping)super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
        mapping.setAttributeAccessor((AttributeAccessor)attributeAccessor.clone());
        return mapping;
    }

    /**
     * INTERNAL:
     * Helper method to clone vector of fields (used in aggregate initialization cloning).
     *
     * @param fields TODO
     * @return TODO
     */
    protected Vector cloneFields(Vector fields) {
        Vector clonedFields = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
        for (Enumeration fieldsEnum = fields.elements(); fieldsEnum.hasMoreElements();) {
            clonedFields.addElement(((DatabaseField)fieldsEnum.nextElement()).clone());
        }

        return clonedFields;
    }

    /**
     * This method must be overwritten in the subclasses to return a vector of all the
     * fields this mapping represents.
     *
     * @return TODO
     */
    protected Vector<DatabaseField> collectFields() {
        return NO_FIELDS;
    }

    /**
     * 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
     *
     * @param record TODO
     */
    public void collectQueryParameters(Set<DatabaseField> record){
        //no-op for mappings that do not support PROTECTED cache isolation
    }

    /**
     * INTERNAL:
     * Mapping callback for post-initialization of source and target expression fields
     * created when a mapping's selectionCriteria is created early with uninitialized fields.
     * @see OneToOneMapping#postInitializeSourceAndTargetExpressions()
     * @see OneToManyMapping#postInitializeSourceAndTargetExpressions()
     */
    public void postInitializeSourceAndTargetExpressions() {
        // no-op by default
        // EL Bug 426500
    }

    /**
     * INTERNAL:
     * This method was created in VisualAge.
     * 
     * @param clone TODO
     * @param backup TODO
     * @param owner TODO
     * @param session TODO
     * @return prototype.changeset.ChangeRecord  TODO
     */
    abstract public ChangeRecord compareForChange(Object clone, Object backup, ObjectChangeSet owner, AbstractSession session);

    /**
     * INTERNAL:
     * Compare the attributes belonging to this mapping for the objects.
     *
     * @param firstObject TODO
     * @param secondObject TODO
     * @param session TODO
     * @return TODO
     */
    public abstract boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session);

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this mapping to actual class-based
     * settings
     * This method is implemented by subclasses as necessary.
     *
     * @param classLoader TODO
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        if (hasUnconvertedProperties()) {
            for (String propertyName : getUnconvertedProperties().keySet()) {
                List<String> valuePair = getUnconvertedProperties().get(propertyName);
                String value = valuePair.get(0);
                String valueTypeName = valuePair.get(1);
                Class<?> valueType = null;

                // Have to initialize the valueType now
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        try {
                            valueType = AccessController.doPrivileged(new PrivilegedClassForName<>(valueTypeName, true, classLoader));
                        } catch (PrivilegedActionException exception) {
                            throw ValidationException.classNotFoundWhileConvertingClassNames(valueTypeName, exception.getException());
                        }
                    } else {
                        valueType = PrivilegedAccessHelper.getClassForName(valueTypeName, true, classLoader);
                    }
                } catch (Exception exception) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(valueTypeName, exception);
                }

                // Add the converted property. If the value type is the same
                // as the source (value) type, no conversion is made.
                getProperties().put(propertyName, ConversionManager.getDefaultManager().convertObject(value, valueType));
            }
        }
    }

    /**
     * Convenience method to ensure converters have an opportunity to convert
     * any class names to classes during project setup.
     *
     * @param converter TODO
     * @param classLoader TODO
     */
    protected void convertConverterClassNamesToClasses(Converter converter, ClassLoader classLoader) {
        if (converter instanceof ClassNameConversionRequired) {
            ((ClassNameConversionRequired)converter).convertClassNamesToClasses(classLoader);
        }
    }

    /**
     * INTERNAL:
     * Builder the unit of work value holder.
     * 
     * @param attributeValue TODO
     * @param original TODO
     * @param clone TODO
     * @param row TODO
     * @param cloningSession TODO
     * @param buildDirectlyFromRow indicates that we are building the clone directly
     * from a row as opposed to building the original from the row, putting it in
     * the shared cache, and then cloning the original.
     * @return TODO
     */
    public <T> DatabaseValueHolder<T> createCloneValueHolder(ValueHolderInterface<T> attributeValue, Object original, Object clone, AbstractRecord row, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        throw DescriptorException.invalidMappingOperation(this, "createUnitOfWorkValueHolder");
    }

    /**
     * ADVANCED:
     * Returns true if the mapping references a JPA ID attribute for the CMP3Policy and JPA ID classes.
     *
     * @return TODO
     */
    public boolean derivesId() {
        return derivesId;
    }

    /**
     * INTERNAL:
     * This method is called to update collection tables prior to commit.
     *
     * @param query TODO
     * @param object TODO
     */
    public void earlyPreDelete(DeleteObjectQuery query, Object object) {
    }

    /**
     * INTERNAL:
     * Extract the nested attribute expressions that apply to this mapping.
     * This is used for partial objects, and batch fetching.
     *
     * @param expressions TODO
     * @param newRoot TODO
     * @return TODO
     */
    protected List<Expression> extractNestedExpressions(List<Expression> expressions, ExpressionBuilder newRoot) {
        List<Expression> nestedExpressions = new ArrayList<>(expressions.size());

        /*
         * If the expression closest to to the Builder is for this mapping, that expression is rebuilt using
         * newRoot and added to the nestedExpressions list.
         */
        for (Expression next : expressions) {
            // The expressionBuilder can be one of the locked expressions in
            // the ForUpdateOfClause.
            if (!next.isQueryKeyExpression()) {
                continue;
            }
            QueryKeyExpression expression = (QueryKeyExpression)next;
            ObjectExpression base = expression;
            boolean afterBase = false;

            while (!base.getBaseExpression().isExpressionBuilder()) {
                base = (ObjectExpression)base.getBaseExpression();
                afterBase = true;
            }
            if (base.getName().equals(getAttributeName())) {
                // Only add the nested expressions for the mapping (not the mapping itself).
                if (afterBase) {
                    nestedExpressions.add(expression.rebuildOn(base, newRoot));
                }
            }
        }
        return nestedExpressions;
    }

    /**
     * INTERNAL:
     * Extract the nested attribute expressions that apply to this mapping.
     * This is used for joining, and locking.
     * For aggregates return the nested foreign reference mapping, not the aggregate, as the aggregates are not joined,
     * and share their parent's query.
     *
     * @param expressions TODO
     * @param newRoot TODO
     * @param rootExpressionsAllowed true if newRoot itself can be one of the
     * expressions returned (used for locking)
     * @return TODO
     */
    protected List<Expression> extractNestedNonAggregateExpressions(List<Expression> expressions, ExpressionBuilder newRoot, boolean rootExpressionsAllowed) {
        List<Expression> nestedExpressions = new ArrayList<>(expressions.size());

        /*
         * need to work on all expressions with at least 2 nestings off the base expression builder, excluding
         * aggregateObjectMapping expressions from the count (only ForeignReferenceMapping expressions count).  For those
         * expressions, If the expression closest to to the Builder is for this mapping, that expression is rebuilt using
         * newRoot and added to the nestedExpressions list.
         */
        for (Expression next : expressions) {
            // The expressionBuilder can be one of the locked expressions in
            // the ForUpdateOfClause.
            if (!next.isQueryKeyExpression()) {
                continue;
            }
            QueryKeyExpression expression = (QueryKeyExpression)next;
            ObjectExpression base = expression;
            boolean afterBase = false;
            boolean done = false;

            ObjectExpression prevExpression = base;
            while (!base.getBaseExpression().isExpressionBuilder()&& !done) {
                base = (ObjectExpression)base.getBaseExpression();
                while (!base.isExpressionBuilder() && (base.getMapping() != null && base.getMapping().isAggregateObjectMapping())) {
                    base = (ObjectExpression)base.getBaseExpression();
                }
                if (base.isExpressionBuilder()){
                    done = true;
                    //use the one closest to the expression builder that wasn't an aggregate
                    base = prevExpression;
                } else {
                    prevExpression = base;
                    afterBase = true;
                }
            }
            if (afterBase && base.getName().equals(getAttributeName())) {
                nestedExpressions.add(expression.rebuildOn(base, newRoot));
            } else if (rootExpressionsAllowed && expression.getBaseExpression().isExpressionBuilder() && expression.getName().equals(getAttributeName())) {
                nestedExpressions.add(newRoot);
            }
        }
        return nestedExpressions;
    }

    /**
     * INTERNAL:
     * If there is root expression in the list then indicates whether it shouldUseOuterJoin,
     * otherwise return false.
     *
     * @param expressions TODO
     * @return TODO
     */
    protected boolean hasRootExpressionThatShouldUseOuterJoin(List expressions) {
        for (Iterator expressionsEnum = expressions.iterator();
                 expressionsEnum.hasNext();) {
            Expression next = (Expression)expressionsEnum.next();

            // The expressionBuilder can be one of the locked expressions in
            // the ForUpdateOfClause.
            if (!next.isQueryKeyExpression()) {
                continue;
            }
            QueryKeyExpression expression = (QueryKeyExpression)next;
            if (expression.getBaseExpression().isExpressionBuilder() && expression.getName().equals(getAttributeName())) {
                return expression.shouldUseOuterJoin();
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Used to store un-converted properties, which are subsequenctly converted
     * at runtime (through the convertClassNamesToClasses method.
     *
     * @return TODO
     */
    public boolean hasUnconvertedProperties() {
        return unconvertedProperties != null;
    }

    /**
     * INTERNAL:
     * An object has been serialized from the server to the client.
     * Replace the transient attributes of the remote value holders
     * with client-side objects.
     *
     * @param object TODO
     * @param objectDescriptors TODO
     * @param processedObjects TODO
     * @param query TODO
     * @param session TODO
     */
    public abstract void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session);

    /**
     * INTERNAL:
     * At this point, we realize we don't have indirection;
     * so we need to replace the reference object(s) with
     * the corresponding object(s) from the remote session.
     * The default is to do nothing.
     *
     * @param object TODO
     * @param objectInformation TODO
     * @param processedObjects TODO
     * @param query TODO
     * @param session TODO
     */
    public void fixRealObjectReferences(Object object, Map<Object, ObjectDescriptor> objectInformation, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        // do nothing
    }

    /**
     * ADVANCED:
     * Return the attributeAccessor.
     * The attribute accessor is responsible for setting and retrieving the attribute value
     * from the object for this mapping.
     *
     * @return TODO
     */
    @Override
    public AttributeAccessor getAttributeAccessor() {
        return attributeAccessor;
    }

    /**
     * PUBLIC:
     * The classification type for the attribute this mapping represents
     *
     * @return TODO
     */
    @Override
    public Class<?> getAttributeClassification() {
        return null;
    }

    /**
     * PUBLIC:
     * Return the name of the attribute set in the mapping.
     *
     * @return TODO
     */
    @Override
    public String getAttributeName() {
        // The attribute name on the attributeAccessor will always override any attribute already set
        // Use the attributeAccessor attribute over the current attribute name
        if (attributeName == null) {
            attributeName = getAttributeAccessor().getAttributeName();
        }
        return attributeName;
    }

    /**
     * INTERNAL:
     * Return the value of an attribute which this mapping represents for an object.
     */
    @Override
    public Object getAttributeValueFromObject(Object object) throws DescriptorException {
        try {
            // PERF: direct-access.
            return this.attributeAccessor.getAttributeValueFromObject(object);
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            throw exception;
        }
    }

    /**
     * INTERNAL:
     * Return the mapping's containerPolicy.
     *
     * @return TODO
     */
    @Override
    public ContainerPolicy getContainerPolicy() {
        throw DescriptorException.invalidMappingOperation(this, "getContainerPolicy");
    }

    /**
     * ADVANCED:
     * Set the maps id value
     *
     * @return TODO
     */
    public DatabaseMapping getDerivedIdMapping() {
        return derivedIdMapping;
    }

    /**
     * INTERNAL:
     * Return the descriptor to which this mapping belongs
     *
     * @return TODO
     */
    @Override
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * INTERNAL:
     * Return the field associated with this mapping if there is exactly one.
     * This is required for object relational mapping to print them, but because
     * they are defined in in an Enterprise context they cannot be cast to.
     * Mappings that have a field include direct mappings and object relational mappings.
     *
     * @return TODO
     */
    @Override
    public DatabaseField getField() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the classification for the field contained in the mapping.
     * This is used to convert the row value to a consistent java value.
     * By default this is unknown.
     */
    public Class<?> getFieldClassification(DatabaseField fieldToClassify) {
        return null;
    }

    /**
     * INTERNAL:
     * Returns the set of fields that should be selected to build this mapping's value(s).
     * This is used by expressions to determine which fields to include in the select clause for non-object expressions.
     *
     * @return TODO
     */
    public Vector getSelectFields() {
        return getFields();
    }

    /**
     * INTERNAL:
     * Returns the table(s) that should be selected to build this mapping's value(s).
     * This is used by expressions to determine which tables to include in the from clause for non-object expressions.
     *
     * @return TODO
     */
    public Vector getSelectTables() {
        return new NonSynchronizedVector<>(0);
    }

    /**
     * INTERNAL:
     * Returns a vector of all the fields this mapping represents.
     *
     * @return TODO
     */
    @Override
    public Vector<DatabaseField> getFields() {
        return this.fields;
    }

    /**
     * INTERNAL:
     * Return the list of fields that should be used if this mapping is used in an order by.
     * null means this mapping does not need to normalize it fields (it is a field).
     */
    public List<Expression> getOrderByNormalizedExpressions(Expression base) {
        return null;
    }

    /**
     * PUBLIC:
     * This method is invoked reflectively on the reference object to return the value of the
     * attribute in the object. This method returns the name of the getMethodName or null if not using method access.
     *
     * @return TODO
     */
    public String getGetMethodName() {
        if (!getAttributeAccessor().isMethodAttributeAccessor()) {
            return null;
        }
        return ((MethodAttributeAccessor)getAttributeAccessor()).getGetMethodName();
    }

    /**
     * ADVANCED:
     * Set the mapped by id value
     *
     * @return TODO
     */
    public boolean hasMapsIdValue() {
        return mapsIdValue != null;
    }

    /**
     * ADVANCED:
     * Set the mapped by id value
     *
     * @return TODO
     */
    public String getMapsIdValue() {
        return mapsIdValue;
    }

    /**
     * INTERNAL:
     * return the object on the client corresponding to the specified object.
     * The default is to simply return the object itself, without worrying about
     * maintaining object identity.
     *
     * @param object TODO
     * @param session TODO
     * @param objectDescriptors TODO
     * @param processedObjects TODO
     * @param query TODO
     * @return TODO
     */
    public Object getObjectCorrespondingTo(Object object, DistributedSession session, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query) {
        return object;
    }

    /**
     * INTERNAL:
     * used as a temporary store for custom SDK usage
     *
     * @return TODO
     */
    public Map getProperties() {
        if (properties == null) {//Lazy initialize to conserve space and allocation time.
            properties = new HashMap(5);
        }
        return properties;
    }

    /**
     * ADVANCED:
     * Allow user defined properties.
     *
     * @param property TODO
     * @return TODO
     */
    public Object getProperty(Object property) {
        if (properties == null) {
            return null;
        }

        return getProperties().get(property);
    }

    /**
     * INTERNAL:
     * Return the value of an attribute unwrapping value holders if required.
     */
    public Object getRealAttributeValueFromObject(Object object, AbstractSession session) throws DescriptorException {
        return getRealAttributeValueFromAttribute(getAttributeValueFromObject(object), object, session);
    }

    /**
     * INTERNAL:
     * Return the value of an attribute unwrapping value holders if required.
     */
    public Object getRealAttributeValueFromAttribute(Object attributeValue, Object object, AbstractSession session) throws DescriptorException {
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Trigger the instantiation of the attribute if lazy.
     */
    public void instantiateAttribute(Object object, AbstractSession session) {
        // Not lazy by default.
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    public boolean isAttributeValueFromObjectInstantiated(Object object) {
        return true;
    }

    /**
     * INTERNAL:
     * Return the value of an attribute, unwrapping value holders if necessary.
     * If the value is null, build a new container.
     */
    public Object getRealCollectionAttributeValueFromObject(Object object, AbstractSession session) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "getRealCollectionAttributeValueFromObject");
    }

    /**
     * PUBLIC:
     * Return the referenceDescriptor. This is a descriptor which is associated with
     * the reference class.
     */
    @Override
    public ClassDescriptor getReferenceDescriptor() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the relationshipPartner mapping for this bi-directional mapping. If the relationshipPartner is null then
     * this is a uni-directional mapping.
     */
    public DatabaseMapping getRelationshipPartner() {
        return null;
    }

    /**
     * PUBLIC:
     * This method is invoked reflectively on the reference object to set the value of the
     * attribute in the object. This method returns the name of the setMethodName or null if not using method access.
     */
    public String getSetMethodName() {
        if (!getAttributeAccessor().isMethodAttributeAccessor()) {
            return null;
        }
        return ((MethodAttributeAccessor)getAttributeAccessor()).getSetMethodName();
    }

    /**
     * INTERNAL:
     * Used to store un-converted properties, which are subsequenctly converted
     * at runtime (through the convertClassNamesToClasses method.
     */
    public Map<String, List<String>> getUnconvertedProperties() {
        if (unconvertedProperties == null) {
            unconvertedProperties = new HashMap<>(5);
        }

        return unconvertedProperties;
    }

    /**
     * INTERNAL:
     * extract and return the appropriate value from the
     * specified remote value holder
     */
    public Object getValueFromRemoteValueHolder(RemoteValueHolder remoteValueHolder) {
        throw DescriptorException.invalidMappingOperation(this, "getValueFromRemoteValueHolder");
    }

    /**
     * INTERNAL:
     * Return the weight of the mapping, used to sort mappings to ensure that
     * DirectToField Mappings get merged first
     */
    public Integer getWeight() {
        return this.weight;
    }

    /**
     * INTERNAL:
     * The returns if the mapping has any constraint dependencies, such as foreign keys and join tables.
     */
    public boolean hasConstraintDependency() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if method access is used.
     */
    public boolean isUsingMethodAccess() {
        return getAttributeAccessor().isMethodAttributeAccessor();
    }

    /**
     * INTERNAL:
     * Return if the mapping has any ownership or other dependency over its target object(s).
     */
    public boolean hasDependency() {
        return false;
    }

    /**
     * INTERNAL:
     * The returns if the mapping has any inverse constraint dependencies, such as foreign keys and join tables.
     */
    public boolean hasInverseConstraintDependency() {
        return false;
    }

    /**
     * INTERNAL:
     * Allow for initialization of properties and validation.
     */
    public void initialize(AbstractSession session) throws DescriptorException {
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isAggregateCollectionMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isAggregateMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isAggregateObjectMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isCollectionMapping() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isDatabaseMapping() {
        return true;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isDirectCollectionMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isDirectMapMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isDirectToFieldMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isElementCollectionMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isForeignReferenceMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Return whether this mapping should be traversed when we are locking
     */
    public boolean isLockableMapping(){
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isManyToManyMapping() {
        return false;
    }

    /**
     * @return the isMapKeyMapping
     */
    public boolean isMapKeyMapping() {
        return isMapKeyMapping;
    }

    /**
     * INTERNAL
     */
    public boolean isMultitenantPrimaryKeyMapping() {
        return false;
    }

    /**
     * @param isMapKeyMapping the isMapKeyMapping to set
     */
    public void setIsMapKeyMapping(boolean isMapKeyMapping) {
        this.isMapKeyMapping = isMapKeyMapping;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isNestedTableMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isObjectReferenceMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isOneToManyMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isOneToOneMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isManyToOneMapping() {
        return false;
    }

    /**
     * Return whether the value of this mapping is optional (that is, can be
     * null). This is a hint and is used when generating DDL.
     */
    public boolean isOptional() {
        return isOptional;
    }

    /**
     * Returns true if this mapping is owned by the parent descriptor.  This is generally based on mapping type
     */
    public boolean isOwned(){
        return false;
    }

    /**
     * INTERNAL:
     * Flags that this mapping is part of a JPA id mapping. It should be
     * temporary though, as the CMP3Policy should be able to figure things
     * out on its own. The problem being that the JPA mapped superclass
     * descriptors are not initialized and do not have a CMP3Policy set by
     * default.
     */
    public boolean isJPAId() {
        return isJPAId;
    }

    /**
     * Return if this mapping is lazy.
     * Lazy has different meaning for different mappings.
     * For basic/direct mappings, this can be used exclude it from the descriptor's
     * default fetch group.  This means that queries will not include the field(s) required
     * by this mapping by default.
     * This can only be used if the descriptor has a FetchGroupManager and class implements
     * the FetchGroupTracker interface (or is weaved).
     * <p>
     * For relationship mappings this should normally be the same value as indirection,
     * however for eager relationships this can be used with indirection to allow
     * indirection locking and change tracking, but still always force instantiation.
     */
    public boolean isLazy() {
        if (isLazy == null) {
            // False by default for mappings without indirection.
            isLazy = Boolean.FALSE;
        }
        return isLazy;
    }

    /**
     * INTERNAL:
     * Flags that this mapping is part of a JPA id mapping. It should be
     * temporary though, as the CMP3Policy should be able to figure things
     * out on its own. The problem being that the JPA mapped superclass
     * descriptors are not initialized and do not have a CMP3Policy set by
     * default.
     */
    public void setIsJPAId() {
        this.isJPAId = true;
    }

    /**
     * Set if this mapping is lazy.
     * This can be used for any mapping type to exclude it from the descriptor's
     * default fetch group.  This means that queries will not include the field(s) required
     * by this mapping by default.
     * This can only be used if the descriptor has a FetchGroupManager and class implements
     * the FetchGroupTracker interface (or is weaved).
     * This is not the same as indirection on relationships (lazy relationships),
     * as it defers the loading of the source object fields, not the relationship.
     */
    public void setIsLazy(boolean isLazy) {
        this.isLazy = isLazy;
    }

    /**
     * INTERNAL:
     * All EIS mappings should implement this method to return true.
     */
    public boolean isEISMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * All relational mappings should implement this method to return true.
     */
    public boolean isRelationalMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * All relational mappings should implement this method to return true.
     */
    public boolean isXMLMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isAbstractDirectMapping() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isAbstractColumnMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isAbstractCompositeDirectCollectionMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isAbstractCompositeObjectMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isAbstractCompositeCollectionMapping() {
        return false;
    }
    /**
     * INTERNAL:
     * Return if this mapping support joining.
     */
    public boolean isJoiningSupported() {
        return false;
    }

    /**
     * INTERNAL:
     * Return if this mapping requires its attribute value to be cloned.
     */
    public boolean isCloningRequired() {
        return true;
    }

    /**
     * INTERNAL:
     * Set by the Object builder during initialization returns true if this mapping
     * is used as a primary key mapping.
     */
    public boolean isPrimaryKeyMapping() {
        return this.isPrimaryKeyMapping;
    }

    /**
     * INTERNAL:
     * Returns true if the mapping should be added to the UnitOfWork's list of private owned
     * objects for private owned orphan removal.
     */
    public boolean isCandidateForPrivateOwnedRemoval() {
        return isPrivateOwned();
    }

    /**
     * INTERNAL:
     * Used when determining if a mapping supports cascaded version optimistic
     * locking.
     */
    public boolean isCascadedLockingSupported() {
        return false;
    }

    /**
     * INTERNAL:
     * Return if this mapping supports change tracking.
     */
    public boolean isChangeTrackingSupported(Project project) {
        return false;
    }

    /**
     * INTERNAL:
     * Return if the mapping has ownership over its target object(s).
     */
    public boolean isPrivateOwned() {
        return false;
    }

    /**
     * Used to signal that this mapping references a protected/isolated entity and requires
     * special merge/object building behaviour.
     *
     */
    public boolean isCacheable() {
        return this.isCacheable;
    }
    /**
     * Used to signal that this mapping references a protected/isolated entity and requires
     * special merge/object building behaviour.
     */
    public void setIsCacheable(boolean cacheable) {
        if (!cacheable) {
            throw ValidationException.operationNotSupported("setIsCacheable");
        }
    }

    /**
     * INTERNAL:
     * Returns true if mapping is read only else false.
     */
    @Override
    public boolean isReadOnly() {
        return isReadOnly;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isReferenceMapping() {
        return false;
    }

    protected boolean isRemotelyInitialized() {
        return isRemotelyInitialized;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isStructureMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isTransformationMapping() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isUnidirectionalOneToManyMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isVariableOneToOneMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    public boolean isDirectToXMLTypeMapping() {
        return false;
    }

    /**
     * INTERNAL:
     * Some mappings support no attribute (transformation and multitenant primary key).
     */
    @Override
    public boolean isWriteOnly() {
        return false;
    }

    /**
     * INTERNAL:
     * Iterate on the appropriate attribute value.
     */
    public abstract void iterate(DescriptorIterator iterator);

    /**
     * INTERNAL:
     * Iterate on the attribute value.
     * The value holder has already been processed.
     */
    public void iterateOnRealAttributeValue(DescriptorIterator iterator, Object realAttributeValue) {
        throw DescriptorException.invalidMappingOperation(this, "iterateOnRealAttributeValue");
    }

    /**
     * Force instantiation of the load group.
     */
    public void load(final Object object, AttributeItem item, final AbstractSession session, final boolean fromFetchGroup) {
        // Do nothing by default.
    }

    /**
     * Force instantiation of all indirections.
     */
    public void loadAll(Object object, AbstractSession session, IdentityHashSet loaded) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * Merge changes from the source to the target object.
     */
    public abstract void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession);

    /**
     * INTERNAL:
     * Merge changes from the source to the target object.
     */
    public abstract void mergeIntoObject(Object target, boolean isTargetUninitialized, Object source, MergeManager mergeManager, AbstractSession targetSession);

    /**
     * INTERNAL:
     * Perform the commit event.
     * This is used in the uow to delay data modifications.
     */
    public void performDataModificationEvent(Object[] event, AbstractSession session) throws DatabaseException, DescriptorException {
        throw DescriptorException.invalidDataModificationEvent(this);
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to delete the reference objects after the actual object is deleted.
     */
    public void postDelete(DeleteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * Allow for initialization of properties and validation that have dependecies no the descriptor
     * being initialized.
     */
    public void postInitialize(AbstractSession session) throws DescriptorException {
        // Nothing by default.
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to insert the reference objects after the actual object is inserted.
     */
    public void postInsert(WriteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to update the reference objects after the actual object is updated.
     */
    public void postUpdate(WriteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to delete the reference objects before the actual object is deleted.
     */
    public void preDelete(DeleteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * Allow for initialization of properties and validation.
     */
    public void preInitialize(AbstractSession session) throws DescriptorException {
        try {
            getAttributeAccessor().initializeAttributes(getDescriptor().getJavaClass());
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            session.getIntegrityChecker().handleError(exception);
        }
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to insert the reference objects before the actual object is inserted.
     */
    public void preInsert(WriteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * A subclass that supports cascade version optimistic locking should
     * implement this method to properly prepare the locking policy for their
     * mapping type.
     */
    public void prepareCascadeLockingPolicy() {
        return;
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Recurse thru the parts to update the reference objects before the actual object is updated.
     */
    public void preUpdate(WriteObjectQuery query) throws DatabaseException {
        return;
    }

    /**
     * INTERNAL:
     * Extract value from the row and set the attribute to this value in the object.
     * return value as this value will have been converted to the appropriate type for
     * the object.
     */
    public Object readFromRowIntoObject(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object targetObject, CacheKey parentCacheKey, ObjectBuildingQuery sourceQuery, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
        Object attributeValue = valueFromRow(databaseRow, joinManager, sourceQuery, parentCacheKey, executionSession, isTargetProtected, null);
        setAttributeValueInObject(targetObject, attributeValue);
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Extract values directly from the result-set.
     * PERF: This is used for optimized object building directly from the result-set.
     */
    public Object readFromResultSetIntoObject(ResultSet resultSet, Object targetObject, ObjectBuildingQuery query, AbstractSession session, DatabaseAccessor accessor, ResultSetMetaData metaData, int columnNumber, DatabasePlatform platform) throws SQLException {
        Object attributeValue = valueFromResultSet(resultSet, query, session, accessor, metaData, columnNumber, platform);
        setAttributeValueInObject(targetObject, attributeValue);
        return attributeValue;
    }

    /**
     * PUBLIC:
     * To make mapping read only.
     * Read-only mappings can be used if two attributes map to the same field.
     * Read-only mappings cannot be used for the primary key or other required fields.
     */
    public void readOnly() {
        setIsReadOnly(true);
    }

    /**
     * PUBLIC:
     * The mapping can be dynamically made either readOnly or readWriteOnly. This makes mapping go back to
     * default mode.
     */
    public void readWrite() {
        setIsReadOnly(false);
    }

    /**
     * INTERNAL:
     * Rehash any hashtables based on fields.
     * This is used to clone descriptors for aggregates, which hammer field names,
     * it is probably better not to hammer the field name and this should be refactored.
     */
    public void rehashFieldDependancies(AbstractSession session) {
        // Should be overwritten by any mapping with fields.
    }

    /**
     * INTERNAL:
     * Once descriptors are serialized to the remote session. All its mappings and reference descriptors are traversed. Usually
     * mappings are initilaized and serialized reference descriptors are replaced with local descriptors if they already exist on the
     * remote session.
     */
    public void remoteInitialization(DistributedSession session) {
        // Remote mappings is initilaized here again because while serializing only the uninitialized data is passed
        // as the initialized data is not serializable.
        if (!isRemotelyInitialized()) {
            getAttributeAccessor().initializeAttributes(getDescriptor().getJavaClass());
            remotelyInitialized();
        }
    }

    /**
     * Set the mapping to be initialized for the remote session.
     */
    protected void remotelyInitialized() {
        isRemotelyInitialized = true;
    }

    /**
     * INTERNAL:
     * replace the value holders in the specified reference object(s)
     */
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
        // by default, do nothing
        return null;
    }

    /**
     * ADVANCED:
     * Set the attributeAccessor.
     * The attribute accessor is responsible for setting and retrieving the attribute value
     * from the object for this mapping.
     * This can be set to an implementor of AttributeAccessor if the attribute
     * requires advanced conversion of the mapping value, or a real attribute does not exist.
     */
    @Override
    public void setAttributeAccessor(AttributeAccessor attributeAccessor) {
        String attributeName = getAttributeName();
        this.attributeAccessor = attributeAccessor;
        if (attributeAccessor.getAttributeName() == null) {
            attributeAccessor.setAttributeName(attributeName);
        }
        this.attributeName = null;
    }

    /**
     * PUBLIC:
     * Sets the name of the attribute in the mapping.
     */
    @Override
    public void setAttributeName(String attributeName) {
        getAttributeAccessor().setAttributeName(attributeName);
        // Clear the mapping attribute name until a getAttributeName() call copies the accessor attributeName
        this.attributeName = null;
    }

    /**
     * INTERNAL:
     * Set the value of the attribute mapped by this mapping.
     */
    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        // PERF: Direct variable access.
        try {
            this.attributeAccessor.setAttributeValueInObject(object, value);
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            throw exception;
        }
    }

    /**
     * INTERNAL:
     * Set the value of the attribute mapped by this mapping,
     * placing it inside a value holder if necessary.
     */
    public void setRealAttributeValueInObject(Object object, Object value) throws DescriptorException {
        try {
            this.setAttributeValueInObject(object, value);
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            throw exception;
        }
    }

    /**
     * INTERNAL:
     * Set the descriptor to which this mapping belongs
     */
    @Override
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    /**
     * INTERNAL:
     * Set the mapping's field collection.
     */
    @Override
    protected void setFields(Vector<DatabaseField> fields) {
        this.fields = fields;
    }

    /**
     * PUBLIC:
     * This method is invoked reflectively on the reference object to return the value of the
     * attribute in the object. This method sets the name of the getMethodName.
     */
    public void setGetMethodName(String methodName) {
        if (methodName == null) {
            return;
        }

        // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
        if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
            String attributeName = this.attributeAccessor.getAttributeName();
            setAttributeAccessor(new MethodAttributeAccessor());
            getAttributeAccessor().setAttributeName(attributeName);
        }

        ((MethodAttributeAccessor)getAttributeAccessor()).setGetMethodName(methodName);
    }

    /**
     * Used to specify whether the value of this mapping may be null.
     * This is used when generating DDL.
     */
    public void setIsOptional(boolean isOptional) {
        this.isOptional = isOptional;
    }

    /**
     * INTERNAL:
     * Set by the Object builder during initialization returns true if this mapping
     * is used as a primary key mapping.
     */
    public void setIsPrimaryKeyMapping(boolean isPrimaryKeyMapping) {
        this.isPrimaryKeyMapping = isPrimaryKeyMapping;
    }

    /**
     * PUBLIC:
     * Set this mapping to be read only.
     * Read-only mappings can be used if two attributes map to the same field.
     * Read-only mappings cannot be used for the primary key or other required fields.
     */
    public void setIsReadOnly(boolean aBoolean) {
        isReadOnly = aBoolean;
    }

    /**
     * ADVANCED:
     * Set the maps id value
     */
    public void setMapsIdValue(String mapsIdValue) {
        this.mapsIdValue = mapsIdValue;
    }

    /**
     * INTERNAL:
     * Allow user defined properties.
     */
    public void setProperties(Map properties) {
        this.properties = properties;
    }

    /**
     * ADVANCED:
     * Allow user defined properties.
     */
    public void setProperty(Object property, Object value) {
        getProperties().put(property, value);
    }

    /**
     * PUBLIC:
     * Set the methodName used to set the value for the mapping's attribute into the object.
     */
    public void setSetMethodName(String methodName) {
        if (methodName == null) {
            return;
        }

        // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
        if (!getAttributeAccessor().isMethodAttributeAccessor()) {
            String attributeName = this.attributeAccessor.getAttributeName();
            setAttributeAccessor(new MethodAttributeAccessor());
            getAttributeAccessor().setAttributeName(attributeName);
        }

        ((MethodAttributeAccessor)getAttributeAccessor()).setSetMethodName(methodName);
    }

    /**
     * ADVANCED:
     * Set the weight of the mapping, used to sort mappings
     * DirectToField Mappings have a default weight of 1 while all other Mappings have a
     * default weight of MAXINT.  Ordering of Mappings can be achieved by setting the weight of
     * a particular mapping to a value within the above mentioned limits.  By ordering mappings
     * the user can control what order relationships are processed by TopLink.
     */

    // CR 4097
    public void setWeight(Integer newWeight) {
        this.weight = newWeight;
    }

    /**
     * ADVANCED:
     * This method is used to add an object to a collection once the changeSet is applied.
     * The referenceKey parameter should only be used for direct Maps.
     */
    public void simpleAddToCollectionChangeRecord(Object referenceKey, Object changeSetToAdd, ObjectChangeSet changeSet, AbstractSession session) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "simpleAddToCollectionChangeRecord");
    }

    /**
     * ADVANCED:
     * This method is used to remove an object from a collection once the changeSet is applied.
     * The referenceKey parameter should only be used for direct Maps.
     */
    public void simpleRemoveFromCollectionChangeRecord(Object referenceKey, Object changeSetToAdd, ObjectChangeSet changeSet, AbstractSession session) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "simpleRemoveFromCollectionChangeRecord");
    }

    /**
     * INTERNAL:
     * Print the mapping attribute name, this is used in error messages.
     */
    @Override
    public String toString() {
        return getClass().getName() + "[" + getAttributeName() + "]";
    }

    /**
     * INTERNAL:
     * Allow for subclasses to perform validation.
     */
    public void validateAfterInitialization(AbstractSession session) throws DescriptorException {
    }

    /**
     * INTERNAL:
     * Allow for subclasses to perform validation.
     */
    public void validateBeforeInitialization(AbstractSession session) throws DescriptorException {
    }

    /**
     * INTERNAL:
     * A subclass should extract the value from the object for the field, if it does not map the field then
     * it should return null.
     * Return the Value from the object.
     */
    @Override
    public Object valueFromObject(Object anObject, DatabaseField field, AbstractSession session) {
        return null;
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Returns the value for the mapping from the database row.
     */
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, boolean isTargetProtected) throws DatabaseException {
        return valueFromRow(row, joinManager, query, null, query.getExecutionSession(), isTargetProtected, null);
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Returns the value for the mapping from the database row.
     * The execution session is the session the query was executed on,
     * and its platform should be used for data conversion.
     */
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, CacheKey cacheKey, AbstractSession session, boolean isTargetProtected, Boolean[] wasCacheUsed) throws DatabaseException {
        return null;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping is in SerializedObjectPolicy's sopObject.
     */
    public boolean isInSopObject() {
        return this.isInSopObject == null || this.isInSopObject;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping is in SerializedObjectPolicy's sopObject and not out of it.
     */
    public boolean isInOnlySopObject() {
        return this.isInSopObject != null && this.isInSopObject;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping is out of SerializedObjectPolicy's sopObject.
     */
    public boolean isOutSopObject() {
        return this.isInSopObject == null || !this.isInSopObject;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping is out of SerializedObjectPolicy's sopObject and not in it.
     */
    public boolean isOutOnlySopObject() {
        return this.isInSopObject != null && !this.isInSopObject;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping is both in and out of SerializedObjectPolicy's sopObject.
     */
    public boolean isInAndOutSopObject() {
        return this.isInSopObject == null;
    }

    /**
     * INTERNAL:
     * Set the mapping is in SerializedObjectPolicy's sopObject.
     */
    public void setIsInSopObject() {
        this.isInSopObject = Boolean.TRUE;
    }

    /**
     * INTERNAL:
     * Set the mapping is out of SerializedObjectPolicy's sopObject.
     */
    public void setIsOutSopObject() {
        this.isInSopObject = Boolean.FALSE;
    }

    /**
     * INTERNAL:
     * Set the mapping is both in and out of SerializedObjectPolicy's sopObject
     */
    public void setIsInAndOutSopObject() {
        this.isInSopObject = null;
    }

    /**
     * INTERNAL:
     * Indicates whether the mapping (or at least one of its nested mappings, at any nested depth)
     * references an entity.
     * To return true the mapping (or nested mapping) should be ForeignReferenceMapping with non-null and non-aggregate reference descriptor.
     */
    public boolean hasNestedIdentityReference() {
        return false;
    }

    /**
     * INTERNAL:
     * Returns the value for the mapping directly from the result-set.
     * PERF: Used for optimized object building.
     */
    public Object valueFromResultSet(ResultSet resultSet, ObjectBuildingQuery query, AbstractSession session, DatabaseAccessor accessor, ResultSetMetaData metaData, int columnNumber, DatabasePlatform platform) throws SQLException {
        throw DescriptorException.invalidMappingOperation(this, "valueFromResultSet");
    }

    /**
     * INTERNAL:
     * To verify if the specified object has been deleted or not.
     */
    public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException {
        return true;
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Write the foreign key values from the attribute to the row.
     */

    public void writeFromAttributeIntoRow(Object attribute, AbstractRecord row, AbstractSession session)
    {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Write the attribute value from the object to the row.
     */
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * This row is built for shallow insert which happens in case of bidirectional inserts.
     * If mapping overrides this method it must override writeFromObjectIntoRowForUpdateAfterShallowInsert method, too.
     */
    public void writeFromObjectIntoRowForShallowInsert(Object object, AbstractRecord row, AbstractSession session) {
        writeFromObjectIntoRow(object, row, session, WriteType.INSERT);
    }

    /**
     * INTERNAL:
     * This row is built for update after shallow insert which happens in case of bidirectional inserts.
     * It contains the foreign keys with non null values that were set to null for shallow insert.
     * If mapping overrides writeFromObjectIntoRowForShallowInsert method it must override this one, too.
     */
    public void writeFromObjectIntoRowForUpdateAfterShallowInsert(Object object, AbstractRecord databaseRow, AbstractSession session, DatabaseTable table) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * This row is built for update before shallow delete which happens in case of bidirectional inserts.
     * It contains the same fields as the row built by writeFromObjectIntoRowForUpdateAfterShallowInsert, but all the values are null.
     */
    public void writeFromObjectIntoRowForUpdateBeforeShallowDelete(Object object, AbstractRecord databaseRow, AbstractSession session, DatabaseTable table) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Write the attribute value from the object to the row.
     */
    public void writeFromObjectIntoRowWithChangeRecord(ChangeRecord changeRecord, AbstractRecord row, AbstractSession session, WriteType writeType) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * This row is built for shallow insert which happens in case of bidirectional inserts.
     */
    public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(ChangeRecord changeRecord, AbstractRecord row, AbstractSession session) {
        writeFromObjectIntoRowWithChangeRecord(changeRecord, row, session, WriteType.INSERT);
    }

    /**
     * INTERNAL:
     */
    public void writeFromObjectIntoRowForUpdate(WriteObjectQuery query, AbstractRecord row) {
        writeFromObjectIntoRow(query.getObject(), row, query.getSession(), WriteType.UPDATE);
    }

    /**
     * INTERNAL:
     * A subclass should implement this method if it wants different behavior.
     * Write the attribute value from the object to the row.
     */
    public void writeFromObjectIntoRowForWhereClause(ObjectLevelModifyQuery query, AbstractRecord row) {
        Object object;
        if (query.isDeleteObjectQuery()) {
            object = query.getObject();
        } else {
            object = query.getBackupClone();
        }
        writeFromObjectIntoRow(object, row, query.getSession(), WriteType.UNDEFINED);
    }

    /**
     * INTERNAL:
     * Write fields needed for insert into the template for with null values.
     */
    public void writeInsertFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * Write fields needed for update into the template for with null values.
     * By default inserted fields are used.
     */
    public void writeUpdateFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) {
        writeInsertFieldsIntoRow(databaseRow, session);
    }

    /**
     * INTERNAL:
     * Either create a new change record or update the change record with the new value.
     * This is used by attribute change tracking.
     */
    public void updateChangeRecord(Object clone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "updateChangeRecord");
    }

    /**
     * INTERNAL:
     * Add or removes a new value and its change set to the collection change record based on the event passed in.  This is used by
     * attribute change tracking.
     */
    public void updateCollectionChangeRecord(org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent event, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "updateCollectionChangeRecord");
    }

    /**
     * INTERNAL:
     * Set the change listener if required.
     * This is required for collections and aggregates or other change tracked mutable objects.
     * This is used for resuming or flushing units of work.
     */
    public void setChangeListener(Object clone, PropertyChangeListener listener, UnitOfWorkImpl uow) {
        // Nothing by default.
    }

    /**
     * ADVANCED:
     * Used to indicate the mapping references a JPA ID or MapsId attribute
     * for the CMP3Policy and JPA Id classes (as well as Embeddable Id classes).
     * This is different from isPrimaryKeyMapping, as an ID mapping is user
     * specified and can be read only, as long as another writable mapping for
     * the field exists.
     */
    public void setDerivesId(boolean derivesId) {
        this.derivesId = derivesId;
    }

    /**
     * ADVANCED:
     * Used to indicate the mapping references a JPA ID or MapsId attribute
     * for the CMP3Policy and JPA Id classes (as well as Embeddable Id classes).
     * This is different from isPrimaryKeyMapping, as an ID mapping is user
     * specified and can be read only, as long as another writable mapping for
     * the field exists.
     */
    public void setDerivedIdMapping(DatabaseMapping derivedIdMapping) {
        this.derivedIdMapping = derivedIdMapping;
    }

    /**
     * INTERNAL:
     * Directly build a change record without comparison
     */
    public ChangeRecord buildChangeRecord(Object newValue, ObjectChangeSet owner, AbstractSession session) throws DescriptorException {
        throw DescriptorException.invalidMappingOperation(this, "buildChangeRecord");
    }

    /**
     * INTERNAL:
     * Overridden by mappings that require additional processing of the change record after the record has been calculated.
     */
    public void postCalculateChanges(org.eclipse.persistence.sessions.changesets.ChangeRecord changeRecord, UnitOfWorkImpl uow) {
    }
    /**
     * INTERNAL:
     * Overridden by mappings that require objects to be deleted contribute to change set creation.
     */
    public void postCalculateChangesOnDeleted(Object deletedObject, UnitOfWorkChangeSet uowChangeSet, UnitOfWorkImpl uow) {
    }

    /**
     * INTERNAL:
     * Overridden by mappings that require objects to be deleted contribute to change set creation.
     */
    public void recordPrivateOwnedRemovals(Object object, UnitOfWorkImpl uow) {
    }
}
