/*
 * 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.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 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 != null && 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 DatabaseValueHolder createCloneValueHolder(ValueHolderInterface 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 objectDescriptors, Map 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 objectInformation, Map 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 objectDescriptors, Map 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) {
    }
}
