FileDocCategorySizeDatePackage
ForeignReferenceMapping.javaAPI DocGlassfish v2 API42323Thu May 24 05:06:46 BST 2007oracle.toplink.essentials.mappings

ForeignReferenceMapping

public abstract class ForeignReferenceMapping extends DatabaseMapping
Purpose: Abstract class for relationship mappings

Fields Summary
protected Class
referenceClass
This is used only in descriptor proxy in remote session
protected String
referenceClassName
protected transient AbstractSession
tempInitSession
The session is temporarily used for initialization. Once used, it is set to null
protected transient ClassDescriptor
referenceDescriptor
The descriptor of the reference class.
protected transient ReadQuery
selectionQuery
This query is used to read referenced objects for this mapping.
protected boolean
isPrivateOwned
Indicates whether the referenced object is privately owned or not.
protected IndirectionPolicy
indirectionPolicy
Implements indirection behavior
protected transient boolean
hasCustomSelectionQuery
Indicates whether the selection query is TopLink generated or defined by the user.
protected DatabaseMapping
relationshipPartner
Used to reference the other half of a bi-directional relationship.
protected String
relationshipPartnerAttributeName
Set by users, used to retreive the backpointer for this mapping
protected boolean
cascadePersist
Cascading flags used by the EntityManager
protected boolean
cascadeMerge
protected boolean
cascadeRefresh
protected boolean
cascadeRemove
Constructors Summary
protected ForeignReferenceMapping()

        this.isPrivateOwned = false;
        this.hasCustomSelectionQuery = false;
        this.useBasicIndirection();
        this.cascadePersist = false;
        this.cascadeMerge = false;
        this.cascadeRefresh = false;
        this.cascadeRemove = false;
    
Methods Summary
public voidbuildBackupClone(java.lang.Object clone, java.lang.Object backup, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork)
INTERNAL: Clone the attribute from the clone and assign it to the backup.

        Object attributeValue = getAttributeValueFromObject(clone);
        Object clonedAttributeValue = getIndirectionPolicy().backupCloneAttribute(attributeValue, clone, backup, unitOfWork);
        setAttributeValueInObject(backup, clonedAttributeValue);
    
public abstract java.lang.ObjectbuildBackupCloneForPartObject(java.lang.Object attributeValue, java.lang.Object clone, java.lang.Object backup, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork)
INTERNAL: Used during building the backup shallow copy to copy the target object without re-registering it.

public voidbuildClone(java.lang.Object original, java.lang.Object clone, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinedAttributeManager)
INTERNAL: Clone the attribute from the original and assign it to the clone.

        Object attributeValue = getAttributeValueFromObject(original);
        Object clonedAttributeValue = getIndirectionPolicy().cloneAttribute(attributeValue, original, clone, unitOfWork, false);// building clone from an original not a row.
        //GFBug#404  Trigger the value holder of the joined attribute if shouldCascadeCloneToJoinedRelationship (joinedAttributeManager != null)
        if ((clonedAttributeValue != null) && (joinedAttributeManager != null)) {
            if (joinedAttributeManager.hasJoinedAttributes()) {
                if (joinedAttributeManager.getJoinedAttributes().contains(getAttributeName())) {
                     if (IndirectContainer.class.isAssignableFrom(clonedAttributeValue.getClass())) {
                         ((IndirectContainer)clonedAttributeValue).getValueHolder().getValue();
                     } else if (ValueHolderInterface.class.isAssignableFrom(clonedAttributeValue.getClass())) {
                         ((ValueHolderInterface)clonedAttributeValue).getValue();
                     }
                }
            }
        }
        setAttributeValueInObject(clone, clonedAttributeValue);
    
public abstract java.lang.ObjectbuildCloneForPartObject(java.lang.Object attributeValue, java.lang.Object original, java.lang.Object clone, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork, boolean isExisting)
INTERNAL: Require for cloning, the part must be cloned.

public voidbuildCloneFromRow(oracle.toplink.essentials.internal.sessions.AbstractRecord databaseRow, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, java.lang.Object clone, oracle.toplink.essentials.queryframework.ObjectBuildingQuery sourceQuery, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL: A combination of readFromRowIntoObject and buildClone.

buildClone assumes the attribute value exists on the original and can simply be copied.

readFromRowIntoObject assumes that one is building an original.

Both of the above assumptions are false in this method, and actually attempts to do both at the same time.

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.

        Object attributeValue = valueFromRow(databaseRow, joinManager, sourceQuery, executionSession);
        Object clonedAttributeValue = getIndirectionPolicy().cloneAttribute(attributeValue, null,// no original
                                                                            clone, unitOfWork, true);// building clone directly from row.
        setAttributeValueInObject(clone, clonedAttributeValue);
    
public java.lang.Objectclone()
INTERNAL: The mapping clones itself to create deep copy.

        ForeignReferenceMapping clone = (ForeignReferenceMapping)super.clone();

        clone.setIndirectionPolicy((IndirectionPolicy)indirectionPolicy.clone());
        clone.setSelectionQuery((ReadQuery)getSelectionQuery().clone());

        return clone;
    
public booleancompareObjects(java.lang.Object firstObject, java.lang.Object secondObject, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Compare the attributes belonging to this mapping for the objects.

        if (isPrivateOwned()) {
            return compareObjectsWithPrivateOwned(firstObject, secondObject, session);
        } else {
            return compareObjectsWithoutPrivateOwned(firstObject, secondObject, session);
        }
    
protected abstract booleancompareObjectsWithPrivateOwned(java.lang.Object first, java.lang.Object second, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Compare two objects if their parts are private owned

protected abstract booleancompareObjectsWithoutPrivateOwned(java.lang.Object first, java.lang.Object second, oracle.toplink.essentials.internal.sessions.AbstractSession session)
Compare two objects if their parts are not private owned

public voidconvertClassNamesToClasses(java.lang.ClassLoader classLoader)
INTERNAL: Convert all the class-name-based settings in this mapping to actual class-based settings. This method is used when converting a project that has been built with class names to a project with classes.

param
classLoader

        super.convertClassNamesToClasses(classLoader);

        // DirectCollection mappings don't require a reference class.
        if (getReferenceClassName() != null) {
            Class referenceClass = null;
            try{
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        referenceClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(getReferenceClassName(), true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(getReferenceClassName(), exception.getException());
                    }
                } else {
                    referenceClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(getReferenceClassName(), true, classLoader);
                }
            } catch (ClassNotFoundException exc){
                throw ValidationException.classNotFoundWhileConvertingClassNames(getReferenceClassName(), exc);
            }
            setReferenceClass(referenceClass);
        }
    
public oracle.toplink.essentials.internal.indirection.UnitOfWorkValueHoldercreateUnitOfWorkValueHolder(oracle.toplink.essentials.indirection.ValueHolderInterface attributeValue, java.lang.Object original, java.lang.Object clone, oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork, boolean buildDirectlyFromRow)
INTERNAL: Builder the unit of work value holder. Ignore the original object.

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 new UnitOfWorkQueryValueHolder(attributeValue, clone, this, row, unitOfWork);
    
protected booleandontDoMerge(java.lang.Object target, java.lang.Object source, oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)
INTERNAL: Return true if the merge should be bypassed. This would be the case for several reasons, depending on the kind of merge taking place.

        if (!shouldMergeCascadeReference(mergeManager)) {
            return true;
        }
        if (mergeManager.shouldMergeOriginalIntoWorkingCopy()) {
            // For reverts we are more concerned about the target than the source.
            if (!isAttributeValueInstantiated(target)) {
                return true;
            }
        } else {
            if (mergeManager.shouldRefreshRemoteObject() && shouldMergeCascadeParts(mergeManager) && usesIndirection()) {
                return true;
            } else {
                if (!isAttributeValueInstantiated(source)) {
                    return true;
                }
            }
        }
        return false;
    
public voiddontUseIndirection()
PUBLIC: Indirection means that a ValueHolder will be put in-between the attribute and the real object. This allows for the reading of the target from the database to be delayed until accessed. This defaults to true and is strongly suggested as it give a huge performance gain.

        setIndirectionPolicy(new NoIndirectionPolicy());
    
public java.lang.ObjectgetAttributeValueFromObject(java.lang.Object object)
INTERNAL: Return the value of an attribute which this mapping represents for an object.

        Object attributeValue = super.getAttributeValueFromObject(object);
        Object indirectionValue = getIndirectionPolicy().validateAttributeOfInstantiatedObject(attributeValue);

        // PERF: Allow the indirection policy to initialize null attribute values,
        // this allows the indirection objects to not be initialized in the constructor.
        if (indirectionValue != attributeValue) {
            setAttributeValueInObject(object, indirectionValue);
            attributeValue = indirectionValue;
        }
        return attributeValue;
    
public java.lang.ObjectgetAttributeValueWithClonedValueHolders(java.lang.Object object)
INTERNAL: Returns the attribute value from the reference object. If the attribute is using indirection the value of the value-holder is returned. If the value holder is not instantiated then it is instantiated.

        Object attributeValue = getAttributeValueFromObject(object);
        if (attributeValue instanceof DatabaseValueHolder){
            return ((DatabaseValueHolder)attributeValue).clone();
        } else if (attributeValue instanceof ValueHolder){
            return ((ValueHolder)attributeValue).clone();
        }
        return attributeValue;
    
public oracle.toplink.essentials.internal.indirection.IndirectionPolicygetIndirectionPolicy()
INTERNAL: Return the mapping's indirection policy.

        return indirectionPolicy;
    
public oracle.toplink.essentials.expressions.ExpressiongetJoinCriteria(oracle.toplink.essentials.internal.expressions.QueryKeyExpression exp)
INTERNAL: Returns the join criteria stored in the mapping selection query. This criteria is used to read reference objects across the tables from the database.

        Expression selectionCriteria = getSelectionCriteria();
        return exp.getBaseExpression().twist(selectionCriteria, exp);
    
public java.lang.ObjectgetRealAttributeValueFromObject(java.lang.Object object, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Returns the attribute value from the reference object. If the attribute is using indirection the value of the value-holder is returned. If the value holder is not instantiated then it is instantiated.

            return getIndirectionPolicy().getRealAttributeValueFromObject(object, getAttributeValueFromObject(object));
    
public java.lang.ClassgetReferenceClass()
PUBLIC: Returns the reference class.

        return referenceClass;
    
public java.lang.StringgetReferenceClassName()
INTERNAL: Returns the reference class name.

        if ((referenceClassName == null) && (referenceClass != null)) {
            referenceClassName = referenceClass.getName();
        }
        return referenceClassName;
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetReferenceDescriptor()
INTERNAL: Return the referenceDescriptor. This is a descriptor which is associated with the reference class.

        if (referenceDescriptor == null) {
            if (getTempSession() == null) {
                return null;
            } else {
                referenceDescriptor = getTempSession().getDescriptor(getReferenceClass());
            }
        }

        return referenceDescriptor;
    
public oracle.toplink.essentials.mappings.DatabaseMappinggetRelationshipPartner()
INTERNAL: Return the relationshipPartner mapping for this bi-directional mapping. If the relationshipPartner is null then this is a uni-directional mapping.

        if ((this.relationshipPartner == null) && (this.relationshipPartnerAttributeName != null)) {
            setRelationshipPartner(getReferenceDescriptor().getMappingForAttributeName(getRelationshipPartnerAttributeName()));
        }
        return this.relationshipPartner;
    
public java.lang.StringgetRelationshipPartnerAttributeName()
PUBLIC: Use this method retreive the relationship partner attribute name of this bidirectional Mapping.

        return this.relationshipPartnerAttributeName;
    
public oracle.toplink.essentials.expressions.ExpressiongetSelectionCriteria()
INTERNAL: Returns the selection criteria stored in the mapping selection query. This criteria is used to read reference objects from the database.

        return getSelectionQuery().getSelectionCriteria();
    
public oracle.toplink.essentials.queryframework.ReadQuerygetSelectionQuery()
INTERNAL: Returns the read query assoicated with the mapping.

        return selectionQuery;
    
protected oracle.toplink.essentials.internal.sessions.AbstractSessiongetTempSession()

        return tempInitSession;
    
public booleanhasCustomSelectionQuery()
INTERNAL: Indicates whether the selection query is TopLink generated or defined by the user.

        return hasCustomSelectionQuery;
    
public voidinitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialize the state of mapping.

        super.initialize(session);
        initializeReferenceDescriptor(session);
        initializeSelectionQuery(session);
        getIndirectionPolicy().initialize();
    
protected voidinitializeReferenceDescriptor(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Initialize and set the descriptor for the referenced class in this mapping.

        if (getReferenceClass() == null) {
            throw DescriptorException.referenceClassNotSpecified(this);
        }

        ClassDescriptor refDescriptor = session.getDescriptor(getReferenceClass());

        if (refDescriptor == null) {
            throw DescriptorException.descriptorIsMissing(getReferenceClass().getName(), this);
        }

        if (refDescriptor.isAggregateDescriptor() && (!isAggregateCollectionMapping())) {
            throw DescriptorException.referenceDescriptorCannotBeAggregate(this);
        }

        // can not be isolated if it is null.  Seems that only aggregates do not set
        // the owning descriptor on the mapping.
        if ((!((this.getDescriptor() != null) && this.getDescriptor().isIsolated())) && refDescriptor.isIsolated()) {
            throw DescriptorException.isolateDescriptorReferencedBySharedDescriptor(refDescriptor.getJavaClassName(), this.getDescriptor().getJavaClassName(), this);
        }

        setReferenceDescriptor(refDescriptor);
    
protected voidinitializeSelectionQuery(oracle.toplink.essentials.internal.sessions.AbstractSession session)
A subclass should implement this method if it wants non default behaviour.

        if (((ObjectLevelReadQuery)getSelectionQuery()).getReferenceClass() == null) {
            throw DescriptorException.referenceClassNotSpecified(this);
        }

        getSelectionQuery().setDescriptor(getReferenceDescriptor());
    
public booleanisAttributeValueInstantiated(java.lang.Object object)
INTERNAL: The referenced object is checked if it is instantiated or not

        return getIndirectionPolicy().objectIsInstantiated(getAttributeValueFromObject(object));
    
public booleanisCascadeMerge()
PUBLIC: Check cascading value for the MERGE operation.

        return this.cascadeMerge;
    
public booleanisCascadePersist()
PUBLIC: Check cascading value for the CREATE operation.

        return this.cascadePersist;
    
public booleanisCascadeRefresh()
PUBLIC: Check cascading value for the REFRESH operation.

        return this.cascadeRefresh;
    
public booleanisCascadeRemove()
PUBLIC: Check cascading value for the REMOVE operation.

        return this.cascadeRemove;
    
public booleanisForeignReferenceMapping()
INTERNAL:

        return true;
    
public booleanisPrivateOwned()
INTERNAL: Return true if referenced objects are provately owned else false.

        return isPrivateOwned;
    
public voiditerate(oracle.toplink.essentials.internal.descriptors.DescriptorIterator iterator)
INTERNAL: Iterate on the iterator's current object's attribute defined by this mapping. The iterator's settings for cascading and value holders determine how the iteration continues from here.

        Object attributeValue = this.getAttributeValueFromObject(iterator.getVisitedParent());
        this.getIndirectionPolicy().iterateOnAttributeValue(iterator, attributeValue);
    
public abstract voiditerateOnRealAttributeValue(oracle.toplink.essentials.internal.descriptors.DescriptorIterator iterator, java.lang.Object realAttributeValue)
INTERNAL: Iterate on the attribute value. The value holder has already been processed.

protected oracle.toplink.essentials.queryframework.ReadQueryprepareHistoricalQuery(oracle.toplink.essentials.queryframework.ReadQuery targetQuery, oracle.toplink.essentials.queryframework.ObjectLevelReadQuery sourceQuery, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL: Allow for the mapping to perform any historical query additions. Return the new target query.

        return targetQuery;
    
public oracle.toplink.essentials.queryframework.ObjectLevelReadQueryprepareNestedJoins(oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Clone and prepare the JoinedAttributeManager nested JoinedAttributeManager. This is used for nested joining as the JoinedAttributeManager passed to the joined build object.

        // A nested query must be built to pass to the descriptor that looks like the real query execution would.
        ObjectLevelReadQuery nestedQuery = (ObjectLevelReadQuery)((ObjectLevelReadQuery)getSelectionQuery()).deepClone();
        //set session to be the session on which the query is being executed
        nestedQuery.setSession(session);
        // Recompute the joined indexes based on the nested join expressions.
        nestedQuery.getJoinedAttributeManager().setJoinedMappingIndexes_(null);
        nestedQuery.getJoinedAttributeManager().setJoinedMappingExpressions_(new ArrayList(1));
        nestedQuery.getJoinedAttributeManager().setJoinedAttributeExpressions_(extractNestedExpressions(joinManager.getJoinedAttributeExpressions(), nestedQuery.getExpressionBuilder(), false));
        // the next line sets isToManyJoinQuery flag
        nestedQuery.getJoinedAttributeManager().prepareJoinExpressions(session);
        nestedQuery.getJoinedAttributeManager().computeJoiningMappingIndexes(true, session, 0);
        if (joinManager.getBaseQuery().isLockQuery()) {
            ObjectLevelReadQuery baseQuery = ((ObjectLevelReadQuery)joinManager.getBaseQuery());
            if (baseQuery.getLockingClause().isForUpdateOfClause()) {
                ForUpdateOfClause clause = (ForUpdateOfClause)baseQuery.getLockingClause().clone();
                clause.setLockedExpressions(extractNestedExpressions(clause.getLockedExpressions(), nestedQuery.getExpressionBuilder(), true));
                nestedQuery.setLockingClause(clause);
            } else {
                nestedQuery.setLockingClause(baseQuery.getLockingClause());
            }
        }
        nestedQuery.setShouldMaintainCache(joinManager.getBaseQuery().shouldMaintainCache());
        nestedQuery.setShouldRefreshIdentityMapResult(joinManager.getBaseQuery().shouldRefreshIdentityMapResult());
        nestedQuery.setCascadePolicy(joinManager.getBaseQuery().getCascadePolicy());
        nestedQuery.setSession(null);

        return nestedQuery;

    
public voidprivateOwnedRelationship()
PUBLIC: Sets the reference object to be a private owned. The default behaviour is non private owned.

        setIsPrivateOwned(true);
    
public voidsetCascadeAll(boolean value)
PUBLIC: Sets the cascading for all operations.

        setCascadePersist(value);
        setCascadeMerge(value);
        setCascadeRefresh(value);
        setCascadeRemove(value);
    
public voidsetCascadeMerge(boolean value)
PUBLIC: Sets the cascading for the MERGE operation.

        this.cascadeMerge = value;
    
public voidsetCascadePersist(boolean value)
PUBLIC: Sets the cascading for the CREATE operation.

        this.cascadePersist = value;
    
public voidsetCascadeRefresh(boolean value)
PUBLIC: Sets the cascading for the REFRESH operation.

        this.cascadeRefresh = value;
    
public voidsetCascadeRemove(boolean value)
PUBLIC: Sets the cascading for the REMOVE operation.

        this.cascadeRemove = value;
    
public voidsetCustomSelectionQuery(oracle.toplink.essentials.queryframework.ReadQuery query)
PUBLIC: Relationship mappings creates a read query to read reference objects. If this default query needs to be customize then user can specify its own read query to do the reading of reference objects. One must instance of ReadQuery or subclasses of the ReadQuery.

        setSelectionQuery(query);
        setHasCustomSelectionQuery(true);
    
protected voidsetHasCustomSelectionQuery(boolean bool)

        hasCustomSelectionQuery = bool;
    
public voidsetIndirectionPolicy(oracle.toplink.essentials.internal.indirection.IndirectionPolicy indirectionPolicy)
ADVANCED: Set the indirection policy.

        this.indirectionPolicy = indirectionPolicy;
        indirectionPolicy.setMapping(this);
    
public voidsetIsPrivateOwned(boolean isPrivateOwned)
INTERNAL: Used by Gromit

        this.isPrivateOwned = isPrivateOwned;
    
public voidsetRealAttributeValueInObject(java.lang.Object object, java.lang.Object value)
INTERNAL: Set the value of the attribute mapped by this mapping, placing it inside a value holder if necessary. If the value holder is not instantiated then it is instantiated.

        this.getIndirectionPolicy().setRealAttributeValueInObject(object, value);
    
public voidsetReferenceClass(java.lang.Class referenceClass)
PUBLIC: Set the referenced class.

        this.referenceClass = referenceClass;
        if (referenceClass != null) {
            setReferenceClassName(referenceClass.getName());
            // Make sure the reference class of the selectionQuery is set.
            setSelectionQuery(getSelectionQuery());
        }
    
public voidsetReferenceClassName(java.lang.String referenceClassName)
INTERNAL: Used by MW.

        this.referenceClassName = referenceClassName;
    
protected voidsetReferenceDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor aDescriptor)
Set the referenceDescriptor. This is a descriptor which is associated with the reference class.

        referenceDescriptor = aDescriptor;
    
public voidsetRelationshipPartner(oracle.toplink.essentials.mappings.DatabaseMapping mapping)
INTERNAL: Sets the relationshipPartner mapping for this bi-directional mapping. If the relationshipPartner is null then this is a uni-directional mapping.

        this.relationshipPartner = mapping;
    
public voidsetRelationshipPartnerAttributeName(java.lang.String attributeName)
PUBLIC: Use this method to specify the relationship partner attribute name of a bidirectional Mapping. TopLink will use the attribute name to find the back pointer mapping to maintain referential integrity of the bi-directional mappings.

        this.relationshipPartnerAttributeName = attributeName;
    
public voidsetSelectionCall(oracle.toplink.essentials.queryframework.Call call)
PUBLIC: This is a property on the mapping which will allow custom call to be substituted for reading a reference object.

        getSelectionQuery().setCall(call);
        setCustomSelectionQuery(getSelectionQuery());
    
public voidsetSelectionCriteria(oracle.toplink.essentials.expressions.Expression anExpression)
PUBLIC: Sets the selection criteria to be used as a where clause to read reference objects. This criteria is automatically generated by the TopLink if not explicitly specified by the user.

        getSelectionQuery().setSelectionCriteria(anExpression);
    
protected voidsetSelectionQuery(oracle.toplink.essentials.queryframework.ReadQuery aQuery)
Sets the query

        selectionQuery = aQuery;
        // Make sure the reference class of the selectionQuery is set.        
        if ((selectionQuery != null) && selectionQuery.isObjectLevelReadQuery() && (selectionQuery.getReferenceClassName() == null)) {
            ((ObjectLevelReadQuery)selectionQuery).setReferenceClass(getReferenceClass());
        }
    
public voidsetSelectionSQLString(java.lang.String sqlString)
PUBLIC: This is a property on the mapping which will allow custom SQL to be substituted for reading a reference object.

        getSelectionQuery().setSQLString(sqlString);
        setCustomSelectionQuery(getSelectionQuery());
    
protected voidsetTempSession(oracle.toplink.essentials.internal.sessions.AbstractSession session)

        this.tempInitSession = session;
    
public voidsetUsesIndirection(boolean usesIndirection)
PUBLIC: Indirection means that a ValueHolder will be put in-between the attribute and the real object. This allows for the reading of the target from the database to be delayed until accessed. This defaults to true and is strongly suggested as it give a huge performance gain.

see
#useBasicIndirection()
see
#dontUseIndirection()

        if (usesIndirection) {
            useBasicIndirection();
        } else {
            dontUseIndirection();
        }
    
protected booleanshouldInitializeSelectionCriteria()

        if (hasCustomSelectionQuery()) {
            return false;
        }

        if (getSelectionCriteria() == null) {
            return true;
        }

        return false;
    
public booleanshouldMergeCascadeParts(oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)
INTERNAL: Returns true if the merge should cascade to the mappings reference's parts.

        return ((mergeManager.shouldCascadeByMapping() && this.isCascadeMerge()) || (mergeManager.shouldCascadeAllParts()) || (mergeManager.shouldCascadePrivateParts() && isPrivateOwned()));
    
protected booleanshouldMergeCascadeReference(oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)
Returns true if the merge should cascade to the mappings reference.

        if (mergeManager.shouldCascadeReferences()) {
            return true;
        }

        // P2.0.1.3: Was merging references on non-privately owned parts
        // Same logic in:
        return shouldMergeCascadeParts(mergeManager);
    
protected booleanshouldObjectDeleteCascadeToPart(oracle.toplink.essentials.queryframework.WriteObjectQuery query, java.lang.Object object)
INTERNAL: Returns true only if the object is scheduled for deletion.

        return (isPrivateOwned() || query.shouldCascadeAllParts() || query.shouldDependentObjectBeDeleted(object));
    
protected booleanshouldObjectModifyCascadeToParts(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query)
Returns true if any process leading to object modification should also affect its parts Usually used by write, insert and update.

        if (isReadOnly()) {
            return false;
        }

        if (isPrivateOwned()) {
            return true;
        }

        // Only cascade dependents writes in uow.
        if (query.shouldCascadeOnlyDependentParts()) {
            return hasConstraintDependency();
        }

        return query.shouldCascadeAllParts();
    
protected booleanshouldObjectModifyCascadeToPartsForPreDelete(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query)
INTERNAL: Return whether any process leading to object deletion should also affect its parts. Used in preDelete. Note that foreign key dependencies are reversed for deletes: The relationship side having the foreign key must be deleted before the other side is removed.

        if (isReadOnly()) {
            return false;
        }

        // Always cascade for privately-owned parts
        if (isPrivateOwned()) {
            return true;
        }

        // Foreign key dependencies are reversed for deletes
        if (query.shouldCascadeOnlyDependentParts()) {
            return !hasConstraintDependency();
        } 
        
        return query.shouldCascadeAllParts();
    
protected booleanshouldUseValueFromRowWithJoin(oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager)
INTERNAL: Indicates whether valueFromRow should call valueFromRowInternalWithJoin (true) or valueFromRowInternal (false)

        return isJoiningSupported() && (
                joinManager.isAttributeJoined(getDescriptor(), getAttributeName()) ||
                joinManager.getBaseQuery().hasPartialAttributeExpressions()); // only true on OLRQ and above
    
public oracle.toplink.essentials.internal.sessions.AbstractRecordtrimRowForJoin(oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL:

        // CR #... the field for many objects may be in the row,
        // so build the subpartion of the row through the computed values in the query,
        // this also helps the field indexing match.
        if (joinManager.getJoinedMappingIndexes_() != null) {
            Object value = joinManager.getJoinedMappingIndexes_().get(this);
            if(value != null) {
                return trimRowForJoin(row, value, executionSession);
            }
        }
        return row;
    
public oracle.toplink.essentials.internal.sessions.AbstractRecordtrimRowForJoin(oracle.toplink.essentials.internal.sessions.AbstractRecord row, java.lang.Object value, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL:

        // CR #... the field for many objects may be in the row,
        // so build the subpartion of the row through the computed values in the query,
        // this also helps the field indexing match.
        int fieldStartIndex;
        if(value instanceof Integer) {
            fieldStartIndex = ((Integer)value).intValue();
        } else {
            // must be Map of classes to Integers
            Map map = (Map)value;
            Class cls;
            if (getDescriptor().hasInheritance() && getDescriptor().getInheritancePolicy().shouldReadSubclasses()) {
                cls = getDescriptor().getInheritancePolicy().classFromRow(row, executionSession);
            } else {
                cls = getDescriptor().getJavaClass();
            }
            fieldStartIndex = ((Integer)map.get(cls)).intValue();
        }
        Vector trimedFields = Helper.copyVector(row.getFields(), fieldStartIndex, row.size());
        Vector trimedValues = Helper.copyVector(row.getValues(), fieldStartIndex, row.size());
        return new DatabaseRecord(trimedFields, trimedValues);
    
public voiduseBasicIndirection()
PUBLIC: Indirection means that a ValueHolder will be put in-between the attribute and the real object. This allows for the reading of the target from the database to be delayed until accessed. This defaults to true and is strongly suggested as it give a huge performance gain.

        setIndirectionPolicy(new BasicIndirectionPolicy());
    
public voiduseWeavedIndirection(java.lang.String setMethodName)

        setIndirectionPolicy(new WeavedObjectBasicIndirectionPolicy(setMethodName));
    
public booleanusesIndirection()
PUBLIC: Indirection means that some sort of indirection object will be put in-between the attribute and the real object. This allows for the reading of the target from the database to be delayed until accessed. This defaults to true and is strongly suggested as it give a huge performance gain.

        return getIndirectionPolicy().usesIndirection();
    
public voidvalidateBeforeInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: To validate mappings decleration

        super.validateBeforeInitialization(session);

        if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
            Class attributeType = ((InstanceVariableAttributeAccessor)getAttributeAccessor()).getAttributeType();
            getIndirectionPolicy().validateDeclaredAttributeType(attributeType, session.getIntegrityChecker());
        } else if (getAttributeAccessor() instanceof MethodAttributeAccessor) {
            Class returnType = ((MethodAttributeAccessor)getAttributeAccessor()).getGetMethodReturnType();
            getIndirectionPolicy().validateGetMethodReturnType(returnType, session.getIntegrityChecker());

            Class parameterType = ((MethodAttributeAccessor)getAttributeAccessor()).getSetMethodParameterType();
            getIndirectionPolicy().validateSetMethodParameterType(parameterType, session.getIntegrityChecker());
        }
    
public java.lang.ObjectvalueFromRow(oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, oracle.toplink.essentials.queryframework.ObjectBuildingQuery query, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL: Return the value of the reference attribute or a value holder. Check whether the mapping's attribute should be optimized through batch and joining.

        if(shouldUseValueFromRowWithJoin(joinManager)) {
            return valueFromRowInternalWithJoin(row, joinManager, executionSession);
        } else {
            return valueFromRowInternal(row, joinManager, executionSession);
        }
    
protected java.lang.ObjectvalueFromRowInternal(oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL: Return the value of the reference attribute or a value holder. Check whether the mapping's attribute should be optimized through batch and joining.

        // PERF: Direct variable access.
        ReadQuery targetQuery = this.selectionQuery;

        //CR #4365, 3610825 - moved up from the block below, needs to be set with 
        // indirection off. Clone the query and set its id.
        if (!this.indirectionPolicy.usesIndirection()) {
            targetQuery = (ReadQuery)targetQuery.clone();
            targetQuery.setQueryId(joinManager.getBaseQuery().getQueryId());
        }

        // if the source query is cascading then the target query must use the same settings
        if (targetQuery.isObjectLevelReadQuery() && (joinManager.getBaseQuery().shouldCascadeAllParts() || (this.isPrivateOwned && joinManager.getBaseQuery().shouldCascadePrivateParts()) || (this.cascadeRefresh && joinManager.getBaseQuery().shouldCascadeByMapping()))) {
            // If the target query has already been cloned (we're refreshing) avoid 
            // re-cloning the query again.
            if (targetQuery == this.selectionQuery) {
                targetQuery = (ObjectLevelReadQuery)targetQuery.clone();
            }

            ((ObjectLevelReadQuery)targetQuery).setShouldRefreshIdentityMapResult(joinManager.getBaseQuery().shouldRefreshIdentityMapResult());
            targetQuery.setCascadePolicy(joinManager.getBaseQuery().getCascadePolicy());

            // For queries that have turned caching off, such as aggregate collection, leave it off.
            if (targetQuery.shouldMaintainCache()) {
                targetQuery.setShouldMaintainCache(joinManager.getBaseQuery().shouldMaintainCache());
            }
        }
        if (joinManager.getBaseQuery().isObjectLevelReadQuery()){
            targetQuery = prepareHistoricalQuery(targetQuery, (ObjectLevelReadQuery)joinManager.getBaseQuery(), executionSession);
        }

        return this.indirectionPolicy.valueFromQuery(targetQuery, row, executionSession);
    
protected java.lang.ObjectvalueFromRowInternalWithJoin(oracle.toplink.essentials.internal.sessions.AbstractRecord row, oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager, oracle.toplink.essentials.internal.sessions.AbstractSession executionSession)
INTERNAL: If the query used joining or partial attributes, build the target object directly. If isJoiningSupported()==true then this method must be overridden. Currently only 1-1, 1-m and m-m support joining. Potentially agg-col, dc, dm may support it too (agg-col and dc by just implementing isJoiningSupported(){return true;} - but that should be tested).

        throw ValidationException.mappingDoesNotOverrideValueFromRowInternalWithJoin(Helper.getShortClassName(this.getClass()));