FileDocCategorySizeDatePackage
UnitOfWorkQueryValueHolder.javaAPI DocGlassfish v2 API11355Tue May 22 16:54:36 BST 2007oracle.toplink.essentials.internal.indirection

UnitOfWorkQueryValueHolder

public class UnitOfWorkQueryValueHolder extends UnitOfWorkValueHolder
UnitOfWorkQueryValueHolder wraps a database-stored object and implements behavior to access it. The object is read from the database by invoking a user-specified query. This value holder is used only in the unit of work.
author
Sati

Fields Summary
Constructors Summary
protected UnitOfWorkQueryValueHolder(ValueHolderInterface attributeValue, Object clone, DatabaseMapping mapping, UnitOfWorkImpl unitOfWork)

        super(attributeValue, clone, mapping, unitOfWork);
    
public UnitOfWorkQueryValueHolder(ValueHolderInterface attributeValue, Object clone, ForeignReferenceMapping mapping, AbstractRecord row, UnitOfWorkImpl unitOfWork)

        this(attributeValue, clone, mapping, unitOfWork);
        this.row = row;
    
Methods Summary
protected java.lang.ObjectbuildBackupCloneFor(java.lang.Object cloneAttributeValue)
Backup the clone attribute value.

        return getMapping().buildBackupCloneForPartObject(cloneAttributeValue, null, null, getUnitOfWork());
    
public java.lang.ObjectbuildCloneFor(java.lang.Object originalAttributeValue)
Clone the original attribute value.

        return getMapping().buildCloneForPartObject(originalAttributeValue, null, this.relationshipSourceObject, getUnitOfWork(), true);
    
private oracle.toplink.essentials.mappings.ForeignReferenceMappinggetRelationshipPartnerFor(java.lang.Object partnerObject)
Helper method to retrieve the relationship partner mapping. This will take inheritance into account and return the mapping associated with correct subclass if necessary. This is needed for EJB 2.0 inheritance

        ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        if ((partner == null) || (partnerObject == null)) {
            // no partner, nothing to do
            return partner;
        }

        // if the target object is not an instance of the class type associated with the partner
        // mapping, try and look up the same partner mapping but as part of the partnerObject's
        // descriptor.  Only check if inheritance is involved...
        if (partner.getDescriptor().hasInheritance()) {
            ClassDescriptor partnerObjectDescriptor = this.getSession().getDescriptor(partnerObject);
            if (!(partner.getDescriptor().getJavaClass().isAssignableFrom(partnerObjectDescriptor.getJavaClass()))) {
                return (ForeignReferenceMapping)partnerObjectDescriptor.getMappingForAttributeName(partner.getAttributeName());
            }
        }
        return partner;
    
public voidsetValue(java.lang.Object theValue)
Ensure that the backup value holder is populated.

        // Must force instantiation to be able to compare with the old value.
        if (!isInstantiated()) {
            instantiate();
        }
        Object oldValue = getValue();
        super.setValue(theValue);
        updateForeignReferenceSet(theValue, oldValue);
    
public voidupdateForeignReferenceRemove(java.lang.Object value)
INTERNAL: Here we now must check for bi-directional relationship. If the mapping has a relationship partner then we must maintain the original relationship. We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection

        DatabaseMapping sourceMapping = this.getMapping();
        if (sourceMapping == null) {
            //mapping is a transient attribute. If it does not exist then we have been serialized
            return;
        }

        if (sourceMapping.isPrivateOwned()) {
            // don't null out backpointer on private owned relationship because it will cause an
            // extra update.
            return;
        }

        //	ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
        if (partner != null) {
            if (value != null) {
                Object unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
                Object oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
                Object sourceObject = getRelationshipSourceObject();
                
                if ((oldParent == null) || (partner.isCollectionMapping() &&  !(partner.getContainerPolicy().contains(sourceObject, oldParent, getSession())))) {
                    // value has already been set
                    return;
                }

                if (partner.isObjectReferenceMapping()) {
                    // Check if it's already been set to null
                    partner.setRealAttributeValueInObject(unwrappedValue, null);
                } else if (partner.isCollectionMapping()) {
                    // If it is not in the collection then it has already been removed.
                    partner.getContainerPolicy().removeFrom(sourceObject, oldParent, getSession());
                }
            }
        }
    
public voidupdateForeignReferenceSet(java.lang.Object value, java.lang.Object oldValue)
INTERNAL: Here we now must check for bi-directional relationship. If the mapping has a relationship partner then we must maintain the original relationship. We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection

        if ((value != null) && (ClassConstants.Collection_Class.isAssignableFrom(value.getClass()))) {
            //I'm passing a collection into the valueholder not an object
            return;
        }
        if (getMapping() == null) {
            //mapping is a transient attribute. If it does not exist then we have been serialized
            return;
        }

        //	ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
        if (partner != null) {
            if (value != null) {
                Object unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
                Object oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
                Object sourceObject = getRelationshipSourceObject();
                Object wrappedSource = getMapping().getDescriptor().getObjectBuilder().wrapObject(sourceObject, getSession());
                
                if ((oldParent == sourceObject) || (partner.isCollectionMapping() &&  partner.getContainerPolicy().contains(sourceObject, oldParent, getSession()))) {
                    // value has already been set
                    return;
                }

                // Set the Object that was refereceing this value to reference null, or remove value from its collection
                if (oldParent != null) {
                    if (getMapping().isObjectReferenceMapping()) {
                        if (!partner.isCollectionMapping()) {
                            // If the back pointer is a collection it's OK that I'm adding myself into the collection
                            ((ObjectReferenceMapping)getMapping()).setRealAttributeValueInObject(oldParent, null);
                        }
                    } else if (getMapping().isCollectionMapping() && (!partner.isManyToManyMapping())) {
                        getMapping().getContainerPolicy().removeFrom(unwrappedValue, getMapping().getRealAttributeValueFromObject(oldParent, getSession()), getSession());
                    }
                }
                
                if (oldValue != null) {
                    // CR 3487
                    Object unwrappedOldValue = partner.getDescriptor().getObjectBuilder().unwrapObject(oldValue, getSession());

                    // if this object was referencing a different object reset the back pointer on that object
                    if (partner.isObjectReferenceMapping()) {
                        partner.setRealAttributeValueInObject(unwrappedOldValue, null);
                    } else if (partner.isCollectionMapping()) {
                        partner.getContainerPolicy().removeFrom(sourceObject, partner.getRealAttributeValueFromObject(unwrappedOldValue, getSession()), getSession());
                    }
                }

                // Now set the back reference of the value being passed in to point to this object
                if (partner.isObjectReferenceMapping()) {
                    partner.setRealAttributeValueInObject(unwrappedValue, wrappedSource);
                } else if (partner.isCollectionMapping()) {
                    partner.getContainerPolicy().addInto(wrappedSource, oldParent, getSession());
                }
            } else {
                updateForeignReferenceRemove(oldValue);
            }
        }