/** * 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. */ public void useBasicIndirection() { setIndirectionPolicy(new BasicIndirectionPolicy()); }
/** * INTERNAL: * Return the primary key for the reference object (i.e. the object * object referenced by domainObject and specified by mapping). * This key will be used by a RemoteValueHolder. */ public Vector extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) { if (this.objectIsInstantiated(referenceObject)) { return super.extractPrimaryKeyForReferenceObject(((ValueHolderInterface)referenceObject).getValue(), session); } else { return this.getOneToOneMapping().extractPrimaryKeysForReferenceObjectFromRow(this.extractReferenceRow(referenceObject)); } }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by the batchQuery. * In this case, wrap the query in a ValueHolder for later invocation. */ public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) { return new BatchValueHolder(batchQuery, row, this.getForeignReferenceMapping(), originalQuery, parentCacheKey); }
/** * INTERNAL: * Return the primary key for the reference object (i.e. the object * object referenced by domainObject and specified by mapping). * This key will be used by a RemoteValueHolder. */ @Override public Object extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) { if (objectIsEasilyInstantiated(referenceObject)) { return super.extractPrimaryKeyForReferenceObject(((ValueHolderInterface)referenceObject).getValue(), session); } else { return getOneToOneMapping().extractPrimaryKeysForReferenceObjectFromRow(extractReferenceRow(referenceObject)); } }
/** * INTERNAL: * Return a backup clone of the attribute. */ public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) { IndirectContainer container = (IndirectContainer)attributeValue; ValueHolderInterface valueHolder = container.getValueHolder(); ValueHolderInterface newValueHolder = (ValueHolderInterface)super.backupCloneAttribute(valueHolder, clone, backup, unitOfWork); return buildContainer(newValueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate * method on the object and passing it the row and session. * In this case, wrap the row in a ValueHolder for later use. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { return new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); }
/** * INTERNAL: * Return the original indirection object for a unit of work indirection object. */ @Override public Object getOriginalIndirectionObjectForMerge(Object unitOfWorkIndirectionObject, AbstractSession session) { DatabaseValueHolder holder = (DatabaseValueHolder)getOriginalIndirectionObject(unitOfWorkIndirectionObject, session); if (holder != null && holder.getSession()!= null){ holder.setSession(session); } return holder; }
/** * INTERNAL: * Return the original indirection object for a unit of work indirection object. * This is used when building a new object from the unit of work when the original fell out of the cache. */ @Override public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) { return this.getOriginalValueHolder(unitOfWorkIndirectionObject, session); }
/** * INTERNAL: * Return a clone of the attribute. * @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. */ public Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) { IndirectContainer container = (IndirectContainer)attributeValue; ValueHolderInterface valueHolder = container.getValueHolder(); ValueHolderInterface newValueHolder = (ValueHolderInterface)super.cloneAttribute(valueHolder, original, cacheKey, clone, refreshCascade, cloningSession, buildDirectlyFromRow); return buildContainer(newValueHolder); }
/** * Return the "real" attribute value, as opposed to any wrapper. * This will trigger the wrapper to instantiate the value. In a weaved policy, this will * also call the initial setter method to coordinate the values of the valueholder with * the underlying data. */ public Object getRealAttributeValueFromObject(Object object, Object attribute) { Object value = super.getRealAttributeValueFromObject(object, attribute); // Provide the indirection policy with a callback that allows it to do any updates it needs as the result of getting the value. updateValueInObject(object, value, attribute); return value; }
/** * INTERNAL: * Return the primary key for the reference object (i.e. the object * object referenced by domainObject and specified by mapping). * This key will be used by a RemoteValueHolder. */ @Override public Object extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) { if (objectIsEasilyInstantiated(referenceObject)) { return super.extractPrimaryKeyForReferenceObject(((ValueHolderInterface)referenceObject).getValue(), session); } else { return getOneToOneMapping().extractPrimaryKeysForReferenceObjectFromRow(extractReferenceRow(referenceObject)); } }
/** * INTERNAL: * Return a backup clone of the attribute. */ public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) { IndirectContainer container = (IndirectContainer)attributeValue; ValueHolderInterface valueHolder = container.getValueHolder(); ValueHolderInterface newValueHolder = (ValueHolderInterface)super.backupCloneAttribute(valueHolder, clone, backup, unitOfWork); return buildContainer(newValueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate * method on the object and passing it the row and session. * In this case, wrap the row in a ValueHolder for later use. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { return new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); }
/** * INTERNAL: * Return the original indirection object for a unit of work indirection object. */ @Override public Object getOriginalIndirectionObjectForMerge(Object unitOfWorkIndirectionObject, AbstractSession session) { DatabaseValueHolder holder = (DatabaseValueHolder)getOriginalIndirectionObject(unitOfWorkIndirectionObject, session); if (holder != null && holder.getSession()!= null){ holder.setSession(session); } return holder; }
/** * INTERNAL: * Return the original indirection object for a unit of work indirection object. * This is used when building a new object from the unit of work when the original fell out of the cache. */ @Override public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) { return this.getOriginalValueHolder(unitOfWorkIndirectionObject, session); }
/** * INTERNAL: * Return a clone of the attribute. * @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. */ public Object cloneAttribute(Object attributeValue, Object original, Object clone, UnitOfWorkImpl unitOfWork, boolean buildDirectlyFromRow) { IndirectContainer container = (IndirectContainer)attributeValue; ValueHolderInterface valueHolder = container.getValueHolder(); ValueHolderInterface newValueHolder = (ValueHolderInterface)super.cloneAttribute(valueHolder, original, clone, unitOfWork, buildDirectlyFromRow); return buildContainer(newValueHolder); }
/** * Return the "real" attribute value, as opposed to any wrapper. * This will trigger the wrapper to instantiate the value. In a weaved policy, this will * also call the initial setter method to coordinate the values of the valueholder with * the underlying data. */ @Override public Object getRealAttributeValueFromObject(Object object, Object attribute) { boolean wasInstantiated = attribute != null && attribute instanceof ValueHolderInterface && ((ValueHolderInterface)attribute).isInstantiated(); Object value = super.getRealAttributeValueFromObject(object, attribute); // Provide the indirection policy with a callback that allows it to do any updates it needs as the result of getting the value. if (!wasInstantiated && (value != attribute)) { //if the attribute was already unwrapped then do not call this method updateValueInObject(object, value, attribute); } return value; }
/** * PUBLIC: * Indirection means that a ValueHolder will be put in-between the attribute and the real object. * This defaults to false and only required for transformations that perform database access. */ public void useBasicIndirection() { setIndirectionPolicy(new BasicIndirectionPolicy()); }
/** * INTERNAL: * Return a backup clone of the attribute. */ public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) { IndirectContainer container = (IndirectContainer)attributeValue; ValueHolderInterface valueHolder = container.getValueHolder(); ValueHolderInterface newValueHolder = (ValueHolderInterface)super.backupCloneAttribute(valueHolder, clone, backup, unitOfWork); return buildContainer(newValueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate * method on the object and passing it the row and session. * In this case, wrap the row in a ValueHolder for later use. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { return new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); }