Methods Summary |
---|
public void | addAggregateOrderBy(java.lang.String aggregateName, java.lang.String queryKeyName, boolean isDescending)PUBLIC:
Provide order support for queryKeyName in ascending order.
Called from the EJBAnnotationsProcessor when an @OrderBy on an
aggregate is found.
this.hasOrderBy = true;
ReadAllQuery readAllQuery = (ReadAllQuery) getSelectionQuery();
ExpressionBuilder builder = readAllQuery.getExpressionBuilder();
Expression expression = builder.get(aggregateName).get(queryKeyName).toUpperCase();
if (isDescending) {
readAllQuery.addOrdering(expression.descending());
} else {
readAllQuery.addOrdering(expression.ascending());
}
|
public void | addAscendingOrdering(java.lang.String queryKeyName)PUBLIC:
Provide order support for queryKeyName in ascending order
if (queryKeyName == null) {
return;
}
((ReadAllQuery)getSelectionQuery()).addAscendingOrdering(queryKeyName);
|
public void | addDescendingOrdering(java.lang.String queryKeyName)PUBLIC:
Provide order support for queryKeyName in descending order.
if (queryKeyName == null) {
return;
}
((ReadAllQuery)getSelectionQuery()).addDescendingOrdering(queryKeyName);
|
public void | addOrderBy(java.lang.String queryKeyName, boolean isDescending)PUBLIC:
Provide order support for queryKeyName in descending or ascending order.
Called from the EJBAnnotationsProcessor when an @OrderBy is found.
this.hasOrderBy = true;
if (isDescending) {
addDescendingOrdering(queryKeyName);
} else {
addAscendingOrdering(queryKeyName);
}
|
public void | addToCollectionChangeRecord(java.lang.Object newKey, java.lang.Object newValue, oracle.toplink.essentials.internal.sessions.ObjectChangeSet objectChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)INTERNAL:
Add a new value and its change set to the collection change record. This is used by
attribute change tracking.
if (newValue != null) {
ClassDescriptor descriptor;
//PERF: Use referenceDescriptor if it does not have inheritance
if (!getReferenceDescriptor().hasInheritance()) {
descriptor = getReferenceDescriptor();
} else {
descriptor = uow.getDescriptor(newValue);
}
newValue = descriptor.getObjectBuilder().unwrapObject(newValue, uow);
ObjectChangeSet newSet = descriptor.getObjectBuilder().createObjectChangeSet(newValue, (UnitOfWorkChangeSet)objectChangeSet.getUOWChangeSet(), uow);
simpleAddToCollectionChangeRecord(newKey, newSet, objectChangeSet, uow);
}
|
public java.lang.Object | buildBackupCloneForPartObject(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 vector without re-registering the target objects.
// Check for null
if (attributeValue == null) {
return getContainerPolicy().containerInstance(1);
} else {
return getContainerPolicy().cloneFor(attributeValue);
}
|
public oracle.toplink.essentials.internal.sessions.ChangeRecord | buildChangeRecord(java.lang.Object clone, oracle.toplink.essentials.internal.sessions.ObjectChangeSet owner, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
Directly build a change record without comparison
Object cloneAttribute = null;
cloneAttribute = getAttributeValueFromObject(clone);
if ((cloneAttribute != null) && (!getIndirectionPolicy().objectIsInstantiated(cloneAttribute))) {
return null;
}
// 2612538 - the default size of IdentityHashtable (32) is appropriate
IdentityHashMap cloneKeyValues = new IdentityHashMap();
ContainerPolicy cp = getContainerPolicy();
Object cloneObjectCollection = null;
if (cloneAttribute != null) {
cloneObjectCollection = getRealCollectionAttributeValueFromObject(clone, session);
} else {
cloneObjectCollection = cp.containerInstance(1);
}
Object cloneIter = cp.iteratorFor(cloneObjectCollection);
while (cp.hasNext(cloneIter)) {
Object firstObject = cp.next(cloneIter, session);
if (firstObject != null) {
cloneKeyValues.put(firstObject, firstObject);
}
}
CollectionChangeRecord changeRecord = new CollectionChangeRecord(owner);
changeRecord.setAttribute(getAttributeName());
changeRecord.setMapping(this);
changeRecord.addAdditionChange(cloneKeyValues, (UnitOfWorkChangeSet)owner.getUOWChangeSet(), session);
if (changeRecord.hasChanges()) {
return changeRecord;
}
return null;
|
public java.lang.Object | buildCloneForPartObject(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.
Ignore the objects, use the attribute value.
ContainerPolicy containerPolicy = getContainerPolicy();
if (attributeValue == null) {
Object container = containerPolicy.containerInstance(1);
return container;
}
Object clonedAttributeValue = containerPolicy.containerInstance(containerPolicy.sizeFor(attributeValue));
// I need to synchronize here to prevent the collection from changing while I am cloning it.
// This will occur when I am merging into the cache and I am instantiating a UOW valueHolder at the same time
// I can not synchronize around the clone, as this will cause deadlocks, so I will need to copy the collection then create the clones
// I will use a temporary collection to help speed up the process
Object temporaryCollection = null;
synchronized (attributeValue) {
temporaryCollection = containerPolicy.cloneFor(attributeValue);
}
for (Object valuesIterator = containerPolicy.iteratorFor(temporaryCollection);
containerPolicy.hasNext(valuesIterator);) {
Object cloneValue = buildElementClone(containerPolicy.next(valuesIterator, unitOfWork), unitOfWork, isExisting);
containerPolicy.addInto(cloneValue, clonedAttributeValue, unitOfWork);
}
return clonedAttributeValue;
|
public void | buildCopy(java.lang.Object copy, java.lang.Object original, oracle.toplink.essentials.sessions.ObjectCopyingPolicy policy)INTERNAL:
Copy of the attribute of the object.
This is NOT used for unit of work but for templatizing an object.
Object attributeValue = getRealCollectionAttributeValueFromObject(original, policy.getSession());
Object valuesIterator = getContainerPolicy().iteratorFor(attributeValue);
attributeValue = getContainerPolicy().containerInstance(getContainerPolicy().sizeFor(attributeValue));
while (getContainerPolicy().hasNext(valuesIterator)) {
Object originalValue = getContainerPolicy().next(valuesIterator, policy.getSession());
Object copyValue = originalValue;
if (policy.shouldCascadeAllParts() || (policy.shouldCascadePrivateParts() && isPrivateOwned())) {
copyValue = policy.getSession().copyObject(originalValue, policy);
} else {
// Check for backrefs to copies.
copyValue = policy.getCopies().get(originalValue);
if (copyValue == null) {
copyValue = originalValue;
}
}
getContainerPolicy().addInto(copyValue, attributeValue, policy.getSession());
}
setRealAttributeValueInObject(copy, attributeValue);
|
protected java.lang.Object | buildElementClone(java.lang.Object element, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl unitOfWork, boolean isExisting)INTERNAL:
Clone the element, if necessary.
// optimize registration to knowledge of existence
if (isExisting) {
return unitOfWork.registerExistingObject(element);
} else {// not known whether existing or not
return unitOfWork.registerObject(element);
}
|
public void | calculateDeferredChanges(oracle.toplink.essentials.internal.sessions.ChangeRecord changeRecord, oracle.toplink.essentials.internal.sessions.AbstractSession session)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.
CollectionChangeRecord collectionRecord = (CollectionChangeRecord) changeRecord;
//clear incase events were fired since the set of the collection
// collectionRecord.getAddObjectList().clear();
// collectionRecord.getRemoveObjectList().clear();
compareCollectionsForChange(collectionRecord.getOriginalCollection(), collectionRecord.getLatestCollection(), collectionRecord, session);
|
public void | cascadeMerge(java.lang.Object sourceElement, oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)INTERNAL:
Cascade the merge to the component object, if appropriate.
if (shouldMergeCascadeParts(mergeManager)) {
mergeManager.mergeChanges(mergeManager.getObjectToMerge(sourceElement), null);
}
|
public void | cascadePerformRemoveIfRequired(java.lang.Object object, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow, oracle.toplink.essentials.internal.helper.IdentityHashtable visitedObjects)INTERNAL:
Cascade perform delete through mappings that require the cascade
Object cloneAttribute = null;
cloneAttribute = getAttributeValueFromObject(object);
if ((cloneAttribute == null) || (!this.isCascadeRemove())) {
return;
}
ContainerPolicy cp = getContainerPolicy();
Object cloneObjectCollection = null;
cloneObjectCollection = getRealCollectionAttributeValueFromObject(object, uow);
Object cloneIter = cp.iteratorFor(cloneObjectCollection);
while (cp.hasNext(cloneIter)) {
Object nextObject = cp.next(cloneIter, uow);
if (nextObject != null && (! visitedObjects.contains(nextObject)) ){
visitedObjects.put(nextObject, nextObject);
uow.performRemove(nextObject, visitedObjects);
}
}
|
public void | cascadeRegisterNewIfRequired(java.lang.Object object, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow, oracle.toplink.essentials.internal.helper.IdentityHashtable visitedObjects)INTERNAL:
Cascade registerNew for Create through mappings that require the cascade
Object cloneAttribute = null;
cloneAttribute = getAttributeValueFromObject(object);
if ((cloneAttribute == null) || (!this.isCascadePersist()) || (!getIndirectionPolicy().objectIsInstantiated(cloneAttribute))) {
return;
}
ContainerPolicy cp = getContainerPolicy();
Object cloneObjectCollection = null;
cloneObjectCollection = getRealCollectionAttributeValueFromObject(object, uow);
Object cloneIter = cp.iteratorFor(cloneObjectCollection);
while (cp.hasNext(cloneIter)) {
Object nextObject = cp.next(cloneIter, uow);
if (nextObject != null && (! visitedObjects.contains(nextObject)) ){
visitedObjects.put(nextObject, nextObject);
uow.registerNewObjectForPersist(nextObject, visitedObjects);
}
}
|
private void | checkMapClass(java.lang.Class concreteClass)INTERNAL:
Common validation for a collection mapping using a Map class.
// the reference class has to be specified before coming here
if (getReferenceClass() == null) {
throw DescriptorException.referenceClassNotSpecified(this);
}
if (! Helper.classImplementsInterface(concreteClass, ClassConstants.Map_Class)) {
throw ValidationException.illegalContainerClass(concreteClass);
}
|
public void | compareCollectionsForChange(java.lang.Object oldCollection, java.lang.Object newCollection, oracle.toplink.essentials.internal.sessions.ChangeRecord changeRecord, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
This method is used to calculate the differences between two collections.
It is passed to the container policy to calculate the changes.
getContainerPolicy().compareCollectionsForChange(oldCollection, newCollection, (CollectionChangeRecord) changeRecord, session, getReferenceDescriptor());
|
public oracle.toplink.essentials.internal.sessions.ChangeRecord | compareForChange(java.lang.Object clone, java.lang.Object backUp, oracle.toplink.essentials.internal.sessions.ObjectChangeSet owner, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
This method is used to create a change record from comparing two collections
Object cloneAttribute = null;
Object backUpAttribute = null;
Object backUpObjectCollection = null;
cloneAttribute = getAttributeValueFromObject(clone);
if ((cloneAttribute != null) && (!getIndirectionPolicy().objectIsInstantiated(cloneAttribute))) {
return null;
}
if (!owner.isNew()) {// if the changeSet is for a new object then we must record all off the attributes
backUpAttribute = getAttributeValueFromObject(backUp);
if ((cloneAttribute == null) && (backUpAttribute == null)) {
return null;
}
backUpObjectCollection = getRealCollectionAttributeValueFromObject(backUp, session);
}
Object cloneObjectCollection = null;
if (cloneAttribute != null) {
cloneObjectCollection = getRealCollectionAttributeValueFromObject(clone, session);
} else {
cloneObjectCollection = getContainerPolicy().containerInstance(1);
}
CollectionChangeRecord changeRecord = new CollectionChangeRecord(owner);
changeRecord.setAttribute(getAttributeName());
changeRecord.setMapping(this);
compareCollectionsForChange(backUpObjectCollection, cloneObjectCollection, changeRecord, session);
if (changeRecord.hasChanges()) {
return changeRecord;
}
return null;
|
public boolean | compareObjects(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.
Object firstObjectCollection = getRealCollectionAttributeValueFromObject(firstObject, session);
Object secondObjectCollection = getRealCollectionAttributeValueFromObject(secondObject, session);
return super.compareObjects(firstObjectCollection, secondObjectCollection, session);
|
protected void | compareObjectsAndWrite(java.lang.Object previousObjects, java.lang.Object currentObjects, oracle.toplink.essentials.queryframework.WriteObjectQuery query)INTERNAL:
The memory objects are compared and only the changes are written to the database
ContainerPolicy cp = getContainerPolicy();
// If it is for an aggregate collection let it continue so that all of
// the correct values are deleted and then re-added This could be
// changed to make AggregateCollection changes smarter.
if ((query.getObjectChangeSet() != null) && !this.isAggregateCollectionMapping()) {
ObjectChangeSet changeSet = query.getObjectChangeSet();
CollectionChangeRecord record = (CollectionChangeRecord)changeSet.getChangesForAttributeNamed(this.getAttributeName());
if (record != null) {
ObjectChangeSet removedChangeSet = null;
ObjectChangeSet addedChangeSet = null;
UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet)changeSet.getUOWChangeSet();
Enumeration removedObjects = record.getRemoveObjectList().elements();
while (removedObjects.hasMoreElements()) {
removedChangeSet = (ObjectChangeSet)removedObjects.nextElement();
objectRemovedDuringUpdate(query, removedChangeSet.getUnitOfWorkClone());
}
Enumeration addedObjects = record.getAddObjectList().elements();
while (addedObjects.hasMoreElements()) {
addedChangeSet = (ObjectChangeSet)addedObjects.nextElement();
objectAddedDuringUpdate(query, addedChangeSet.getUnitOfWorkClone(), addedChangeSet);
}
}
return;
}
Hashtable previousObjectsByKey = new Hashtable(cp.sizeFor(previousObjects) + 2);// Read from db or from backup in uow.
Hashtable currentObjectsByKey = new Hashtable(cp.sizeFor(currentObjects) + 2);// Current value of object's attribute (clone in uow).
IdentityHashtable cacheKeysOfCurrentObjects = new IdentityHashtable(cp.sizeFor(currentObjects) + 1);
// First index the current objects by their primary key.
for (Object currentObjectsIter = cp.iteratorFor(currentObjects);
cp.hasNext(currentObjectsIter);) {
Object currentObject = cp.next(currentObjectsIter, query.getSession());
try {
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(currentObject, query.getSession());
CacheKey key = new CacheKey(primaryKey);
currentObjectsByKey.put(key, currentObject);
cacheKeysOfCurrentObjects.put(currentObject, key);
} catch (NullPointerException e) {
// For CR#2646 quietly discard nulls added to a collection mapping.
// This try-catch is essentially a null check on currentObject, for
// ideally the customer should check for these themselves.
if (currentObject != null) {
throw e;
}
}
}
// Next index the previous objects (read from db or from backup in uow)
// and process the difference to current (optimized in same loop).
for (Object previousObjectsIter = cp.iteratorFor(previousObjects);
cp.hasNext(previousObjectsIter);) {
Object previousObject = cp.next(previousObjectsIter, query.getSession());
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(previousObject, query.getSession());
CacheKey key = new CacheKey(primaryKey);
previousObjectsByKey.put(key, previousObject);
// Delete must occur first, incase object with same pk is removed and added,
// (technically should not happen, but same applies to unquie constainsts)
if (!currentObjectsByKey.containsKey(key)) {
objectRemovedDuringUpdate(query, previousObject);
}
}
for (Object currentObjectsIter = cp.iteratorFor(currentObjects);
cp.hasNext(currentObjectsIter);) {
Object currentObject = cp.next(currentObjectsIter, query.getSession());
try {
CacheKey cacheKey = (CacheKey)cacheKeysOfCurrentObjects.get(currentObject);
if (!(previousObjectsByKey.containsKey(cacheKey))) {
objectAddedDuringUpdate(query, currentObject, null);
} else {
objectUnchangedDuringUpdate(query, currentObject, previousObjectsByKey, cacheKey);
}
} catch (NullPointerException e) {
// For CR#2646 skip currentObject if it is null.
if (currentObject != null) {
throw e;
}
}
}
|
protected boolean | compareObjectsWithPrivateOwned(java.lang.Object firstCollection, java.lang.Object secondCollection, oracle.toplink.essentials.internal.sessions.AbstractSession session)Compare two objects if their parts are private owned
ContainerPolicy cp = getContainerPolicy();
if (cp.sizeFor(firstCollection) != cp.sizeFor(secondCollection)) {
return false;
}
Object firstIter = cp.iteratorFor(firstCollection);
Object secondIter = cp.iteratorFor(secondCollection);
Hashtable keyValueToObject = new Hashtable(cp.sizeFor(firstCollection) + 2);
CacheKey cacheKey;
while (cp.hasNext(secondIter)) {
Object secondObject = cp.next(secondIter, session);
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session);
keyValueToObject.put(new CacheKey(primaryKey), secondObject);
}
while (cp.hasNext(firstIter)) {
Object firstObject = cp.next(firstIter, session);
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session);
cacheKey = new CacheKey(primaryKey);
if (keyValueToObject.containsKey(cacheKey)) {
Object object = keyValueToObject.get(cacheKey);
if (!session.compareObjects(firstObject, object)) {
return false;
}
} else {
return false;
}
}
return true;
|
protected boolean | compareObjectsWithoutPrivateOwned(java.lang.Object firstCollection, java.lang.Object secondCollection, oracle.toplink.essentials.internal.sessions.AbstractSession session)Compare two objects if their parts are not private owned
ContainerPolicy cp = getContainerPolicy();
if (cp.sizeFor(firstCollection) != cp.sizeFor(secondCollection)) {
return false;
}
Object firstIter = cp.iteratorFor(firstCollection);
Object secondIter = cp.iteratorFor(secondCollection);
Vector keyValue = new Vector();
while (cp.hasNext(secondIter)) {
Object secondObject = cp.next(secondIter, session);
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session);
keyValue.addElement(new CacheKey(primaryKey));
}
while (cp.hasNext(firstIter)) {
Object firstObject = cp.next(firstIter, session);
Vector primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session);
if (!keyValue.contains(new CacheKey(primaryKey))) {
return false;
}
}
return true;
|
public void | convertClassNamesToClasses(java.lang.ClassLoader classLoader)INTERNAL:
Convert all the class-name-based settings in this mapping to actual class-based
settings
This method is implemented by subclasses as necessary.
super.convertClassNamesToClasses(classLoader);
containerPolicy.convertClassNamesToClasses(classLoader);
|
public oracle.toplink.essentials.internal.queryframework.ContainerPolicy | getContainerPolicy()INTERNAL:
Returns the receiver's containerPolicy.
return containerPolicy;
|
protected oracle.toplink.essentials.queryframework.ModifyQuery | getDeleteAllQuery()
if (deleteAllQuery == null) {
deleteAllQuery = new DataModifyQuery();
}
return deleteAllQuery;
|
public java.lang.Object | getRealAttributeValueFromObject(java.lang.Object object, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
Return the value of an attribute, unwrapping value holders if necessary.
Also check to ensure the collection is a vector.
Object value = super.getRealAttributeValueFromObject(object, session);
if (value != null) {
if (!getContainerPolicy().isValidContainer(value)) {
throw DescriptorException.attributeTypeNotValid(this);
}
}
return value;
|
public java.lang.Object | getRealCollectionAttributeValueFromObject(java.lang.Object object, oracle.toplink.essentials.internal.sessions.AbstractSession session)Convenience method.
Return the value of an attribute, unwrapping value holders if necessary.
If the value is null, build a new container.
Object value = this.getRealAttributeValueFromObject(object, session);
if (value == null) {
value = this.getContainerPolicy().containerInstance(1);
}
return value;
|
protected boolean | hasCustomDeleteAllQuery()
return hasCustomDeleteAllQuery;
|
public boolean | hasOrderBy()INTERNAL:
Return true if ascending or descending ordering has been set on this
mapping via the @OrderBy annotation.
return hasOrderBy;
|
public void | initialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
Initialize the state of mapping.
super.initialize(session);
setFields(collectFields());
getContainerPolicy().prepare(getSelectionQuery(), session);
// Check that the container policy is correct for the collection type.
if ((!usesIndirection()) && (!getAttributeAccessor().getAttributeClass().isAssignableFrom(getContainerPolicy().getContainerClass()))) {
throw DescriptorException.incorrectCollectionPolicy(this, getAttributeAccessor().getAttributeClass(), getContainerPolicy().getContainerClass());
}
|
public boolean | isChangeTrackingSupported()INTERNAL:
Return if this mapping supports change tracking.
return true;
|
public boolean | isCollectionMapping()INTERNAL:
return true;
|
public void | iterateOnElement(oracle.toplink.essentials.internal.descriptors.DescriptorIterator iterator, java.lang.Object element)INTERNAL:
Iterate on the specified element.
iterator.iterateReferenceObjectForMapping(element, this);
|
public void | iterateOnRealAttributeValue(oracle.toplink.essentials.internal.descriptors.DescriptorIterator iterator, java.lang.Object realAttributeValue)INTERNAL:
Iterate on the attribute value.
The value holder has already been processed.
if (realAttributeValue == null) {
return;
}
ContainerPolicy cp = getContainerPolicy();
for (Object iter = cp.iteratorFor(realAttributeValue); cp.hasNext(iter);) {
iterateOnElement(iterator, cp.next(iter, iterator.getSession()));
}
|
public void | mergeChangesIntoObject(java.lang.Object target, oracle.toplink.essentials.internal.sessions.ChangeRecord chgRecord, java.lang.Object source, oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)INTERNAL:
Merge changes from the source to the target object. Because this is a
collection mapping, values are added to or removed from the collection
based on the change set.
Object valueOfTarget = null;
Object valueOfSource = null;
AbstractSession parentSession = null;
ContainerPolicy containerPolicy = getContainerPolicy();
CollectionChangeRecord changeRecord = (CollectionChangeRecord) chgRecord;
UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet)changeRecord.getOwner().getUOWChangeSet();
// Collect the changes into a vector. Check to see if the target has an instantiated
// collection, if it does then iterate over the changes and merge the collections.
if (isAttributeValueInstantiated(target)) {
// If it is new will need a new collection.
if (changeRecord.getOwner().isNew()) {
valueOfTarget = containerPolicy.containerInstance(changeRecord.getAddObjectList().size());
} else {
valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession());
}
// Remove must happen before add to allow for changes in hash keys.
// This is required to return the appropriate object from the parent when unwrapping.
if (mergeManager.getSession().isUnitOfWork() && !mergeManager.shouldMergeWorkingCopyIntoBackup()) {
parentSession = ((UnitOfWorkImpl)mergeManager.getSession()).getParent();
} else {
parentSession = mergeManager.getSession();
}
containerPolicy.mergeChanges(changeRecord, valueOfTarget, shouldMergeCascadeParts(mergeManager), mergeManager, parentSession);
} else {
// The valueholder has not been instantiated
if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
return; // do nothing
}
// If I'm not merging on another server then create instance of the collection.
valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
Object iterator = containerPolicy.iteratorFor(valueOfSource);
valueOfTarget = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
while (containerPolicy.hasNext(iterator)) {
// CR2195 - Problem with merging Collection mapping in unit of work and inheritance.
Object objectToMerge = containerPolicy.next(iterator, mergeManager.getSession());
ObjectChangeSet changeSet = (ObjectChangeSet)uowChangeSet.getObjectChangeSetForClone(objectToMerge);
if (shouldMergeCascadeParts(mergeManager) && (valueOfSource != null)) {
mergeManager.mergeChanges(objectToMerge, changeSet);
}
// Let the mergemanager get it because I don't have the change for the object.
// CR2188 - Problem with merging Collection mapping in unit of work and transparent indirection.
containerPolicy.addInto(mergeManager.getTargetVersionOfSourceObject(objectToMerge), valueOfTarget, mergeManager.getSession());
}
}
if (valueOfTarget == null) {
valueOfTarget = containerPolicy.containerInstance();
}
setRealAttributeValueInObject(target, valueOfTarget);
|
public void | mergeIntoObject(java.lang.Object target, boolean isTargetUnInitialized, java.lang.Object source, oracle.toplink.essentials.internal.sessions.MergeManager mergeManager)INTERNAL:
Merge changes from the source to the target object. This merge is only called when a changeSet for the target
does not exist or the target is uninitialized
if (isTargetUnInitialized) {
// This will happen if the target object was removed from the cache before the commit was attempted
if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) {
setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), mergeManager.getSession()));
return;
}
}
if (!shouldMergeCascadeReference(mergeManager)) {
// This is only going to happen on mergeClone, and we should not attempt to merge the reference
return;
}
if (mergeManager.shouldMergeOriginalIntoWorkingCopy()) {
if (!isAttributeValueInstantiated(target)) {
// This will occur when the clone's value has not been instantiated yet and we do not need
// the refresh that attribute
return;
}
} else if (!isAttributeValueInstantiated(source)) {
// I am merging from a clone into an original. No need to do merge if the attribute was never
// modified
return;
}
Object valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
// There is a very special case when merging into the shared cache that the original
// has been refreshed and now has non-instantiated indirection objects.
// Force instantiation is not necessary and can cause problem with JTS drivers.
AbstractSession mergeSession = mergeManager.getSession();
Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeSession);
ContainerPolicy containerPolicy = getContainerPolicy();
boolean fireChangeEvents = false;
if (! mergeManager.shouldMergeOriginalIntoWorkingCopy()){
// if we are copying from original to clone then the source will be
// instantiated anyway and we must continue to use the UnitOfWork
// valueholder in the case of transparent indirection
Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
valueOfTarget = newContainer;
}else{
//bug 3953038 - set a new collection in the object until merge completes, this
// prevents rel-maint. from adding duplicates.
setRealAttributeValueInObject(target, containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource)));
containerPolicy.clear(valueOfTarget);
}
synchronized(valueOfSource){
Object sourceIterator = containerPolicy.iteratorFor(valueOfSource);
while (containerPolicy.hasNext(sourceIterator)) {
Object object = containerPolicy.next(sourceIterator, mergeManager.getSession());
if (object == null){
continue; // skip the null
}
if (shouldMergeCascadeParts(mergeManager)) {
if ((mergeManager.getSession().isUnitOfWork()) && (((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet() != null)) {
// If it is a unit of work, we have to check if I have a change Set fot this object
mergeManager.mergeChanges(mergeManager.getObjectToMerge(object), (ObjectChangeSet)((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet().getObjectChangeSetForClone(object));
} else {
mergeManager.mergeChanges(mergeManager.getObjectToMerge(object), null);
}
}
object = getReferenceDescriptor().getObjectBuilder().wrapObject(mergeManager.getTargetVersionOfSourceObject(object), mergeManager.getSession());
synchronized (valueOfTarget){
containerPolicy.addInto(object, valueOfTarget, mergeManager.getSession());
}
}
}
// Must re-set variable to allow for set method to re-morph changes if the collection is not being stored directly.
setRealAttributeValueInObject(target, valueOfTarget);
|
protected void | objectAddedDuringUpdate(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query, java.lang.Object objectAdded, oracle.toplink.essentials.internal.sessions.ObjectChangeSet changeSet)INTERNAL:
An object was added to the collection during an update, insert it if private.
if (!shouldObjectModifyCascadeToParts(query)) {// Called always for M-M
return;
}
// Only cascade dependents writes in uow.
if (query.shouldCascadeOnlyDependentParts()) {
return;
}
// Insert must not be done for uow or cascaded queries and we must cascade to cascade policy.
// We should distiguish between insert and write (optimization/paraniod).
if (isPrivateOwned()) {
InsertObjectQuery insertQuery = new InsertObjectQuery();
insertQuery.setObject(objectAdded);
insertQuery.setCascadePolicy(query.getCascadePolicy());
query.getSession().executeQuery(insertQuery);
} else {
// Always write for updates, either private or in uow if calling this method.
UnitOfWorkChangeSet uowChangeSet = null;
if ((changeSet == null) && query.getSession().isUnitOfWork() && (((UnitOfWorkImpl)query.getSession()).getUnitOfWorkChangeSet() != null)) {
uowChangeSet = (UnitOfWorkChangeSet)((UnitOfWorkImpl)query.getSession()).getUnitOfWorkChangeSet();
changeSet = (ObjectChangeSet)uowChangeSet.getObjectChangeSetForClone(query.getObject());
}
WriteObjectQuery writeQuery = new WriteObjectQuery();
writeQuery.setObject(objectAdded);
writeQuery.setObjectChangeSet(changeSet);
writeQuery.setCascadePolicy(query.getCascadePolicy());
query.getSession().executeQuery(writeQuery);
}
|
protected void | objectRemovedDuringUpdate(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query, java.lang.Object objectDeleted)INTERNAL:
An object was removed to the collection during an update, delete it if private.
if (isPrivateOwned()) {// Must check ownership for uow and cascading.
if (query.shouldCascadeOnlyDependentParts()) {
// If the session is a unit of work
if (query.getSession().isUnitOfWork()) {
// ...and the object has not been explictly deleted in the unit of work
if (!(((UnitOfWorkImpl)query.getSession()).getDeletedObjects().containsKey(objectDeleted))) {
query.getSession().getCommitManager().addObjectToDelete(objectDeleted);
}
} else {
query.getSession().getCommitManager().addObjectToDelete(objectDeleted);
}
} else {
query.getSession().deleteObject(objectDeleted);
}
}
|
protected void | objectUnchangedDuringUpdate(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query, java.lang.Object object)INTERNAL:
An object is still in the collection, update it as it may have changed.
if (!shouldObjectModifyCascadeToParts(query)) {// Called always for M-M
return;
}
// Only cascade dependents writes in uow.
if (query.shouldCascadeOnlyDependentParts()) {
return;
}
// Always write for updates, either private or in uow if calling this method.
WriteObjectQuery writeQuery = new WriteObjectQuery();
writeQuery.setObject(object);
writeQuery.setCascadePolicy(query.getCascadePolicy());
query.getSession().executeQuery(writeQuery);
|
protected void | objectUnchangedDuringUpdate(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery query, java.lang.Object object, java.util.Hashtable backupclones, oracle.toplink.essentials.internal.identitymaps.CacheKey keys)INTERNAL:
An object is still in the collection, update it as it may have changed.
objectUnchangedDuringUpdate(query, object);
|
protected void | prepareTranslationRow(oracle.toplink.essentials.internal.sessions.AbstractRecord translationRow, java.lang.Object object, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
copies the non primary key information into the row currently used only in ManyToMany
//Do nothing for the generic Collection Mapping
|
protected java.lang.Object | readPrivateOwnedForObject(oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery modifyQuery)INTERNAL:
All the privately owned parts are read
if (modifyQuery.getSession().isUnitOfWork()) {
return getRealCollectionAttributeValueFromObject(modifyQuery.getBackupClone(), modifyQuery.getSession());
} else {
// cr 3819
prepareTranslationRow(modifyQuery.getTranslationRow(), modifyQuery.getObject(), modifyQuery.getSession());
return modifyQuery.getSession().executeQuery(getSelectionQuery(), modifyQuery.getTranslationRow());
}
|
public void | removeFromCollectionChangeRecord(java.lang.Object newKey, java.lang.Object newValue, oracle.toplink.essentials.internal.sessions.ObjectChangeSet objectChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)INTERNAL:
Remove a value and its change set from the collection change record. This is used by
attribute change tracking.
if (newValue != null) {
ClassDescriptor descriptor;
//PERF: Use referenceDescriptor if it does not have inheritance
if (!getReferenceDescriptor().hasInheritance()) {
descriptor = getReferenceDescriptor();
} else {
descriptor = uow.getDescriptor(newValue);
}
newValue = descriptor.getObjectBuilder().unwrapObject(newValue, uow);
ObjectChangeSet newSet = descriptor.getObjectBuilder().createObjectChangeSet(newValue, (UnitOfWorkChangeSet)objectChangeSet.getUOWChangeSet(), uow);
simpleRemoveFromCollectionChangeRecord(newKey, newSet, objectChangeSet, uow);
}
|
public void | setContainerPolicy(oracle.toplink.essentials.internal.queryframework.ContainerPolicy containerPolicy)ADVANCED:
Configure the mapping to use a container policy.
The policy manages the access to the collection.
this.containerPolicy = containerPolicy;
((ReadAllQuery)getSelectionQuery()).setContainerPolicy(containerPolicy);
|
public void | setCustomDeleteAllQuery(oracle.toplink.essentials.queryframework.ModifyQuery query)PUBLIC:
The default delete all query for mapping can be overridden by specifying the new query.
This query is responsible for doing the deletion required by the mapping,
such as deletion of all the rows from join table for M-M, or optimized delete all of target objects for 1-M.
setDeleteAllQuery(query);
setHasCustomDeleteAllQuery(true);
|
public void | setDeleteAllCall(oracle.toplink.essentials.queryframework.Call call)PUBLIC:
Set the receiver's delete all call. This allows the user to override the SQL
generated by TopLink, with there own SQL or procedure call. The arguments are
translated from the fields of the source row.
This call is responsible for doing the deletion required by the mapping,
such as deletion of all the rows from join table for M-M, or optimized delete all of target objects for 1-M.
Example, 'new SQLCall("delete from PROJ_EMP where EMP_ID = #EMP_ID")'.
DataModifyQuery query = new DataModifyQuery();
query.setCall(call);
setCustomDeleteAllQuery(query);
|
protected void | setDeleteAllQuery(oracle.toplink.essentials.queryframework.ModifyQuery query)
deleteAllQuery = query;
|
public void | setDeleteAllSQLString(java.lang.String sqlString)PUBLIC:
Set the receiver's delete all SQL string. This allows the user to override the SQL
generated by TopLink, with there own SQL or procedure call. The arguments are
translated from the fields of the source row, through replacing the field names
marked by '#' with the values for those fields.
This SQL is responsible for doing the deletion required by the mapping,
such as deletion of all the rows from join table for M-M, or optimized delete all of target objects for 1-M.
Example, 'delete from PROJ_EMP where EMP_ID = #EMP_ID'.
DataModifyQuery query = new DataModifyQuery();
query.setSQLString(sqlString);
setCustomDeleteAllQuery(query);
|
protected void | setHasCustomDeleteAllQuery(boolean bool)
hasCustomDeleteAllQuery = bool;
|
public void | setSessionName(java.lang.String name)PUBLIC:
Set the name of the session to execute the mapping's queries under.
This can be used by the session broker to override the default session
to be used for the target class.
getDeleteAllQuery().setSessionName(name);
getSelectionQuery().setSessionName(name);
|
protected boolean | shouldUseValueFromRowWithJoin(oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager joinManager)INTERNAL:
Indicates whether valueFromRow should call valueFromRowInternalWithJoin (true)
or valueFromRowInternal (false)
return joinManager.getDataResults_()!=null && super.shouldUseValueFromRowWithJoin(joinManager);
|
public void | simpleAddToCollectionChangeRecord(java.lang.Object referenceKey, java.lang.Object changeSetToAdd, oracle.toplink.essentials.internal.sessions.ObjectChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)ADVANCED:
This method is used to have an object add to a collection once the
changeSet is applied. The referenceKey parameter should only be used for
direct Maps.
CollectionChangeRecord collectionChangeRecord = (CollectionChangeRecord)changeSet.getChangesForAttributeNamed(this.getAttributeName());
if (collectionChangeRecord == null) {
collectionChangeRecord = new CollectionChangeRecord(changeSet);
collectionChangeRecord.setAttribute(getAttributeName());
collectionChangeRecord.setMapping(this);
collectionChangeRecord.getAddObjectList().put(changeSetToAdd, changeSetToAdd);
collectionChangeRecord.getOrderedAddObjects().add(changeSetToAdd);
changeSet.addChange(collectionChangeRecord);
} else {
getContainerPolicy().recordAddToCollectionInChangeRecord((ObjectChangeSet)changeSetToAdd, collectionChangeRecord);
}
if (referenceKey != null){
((ObjectChangeSet)changeSetToAdd).setNewKey(referenceKey);
}
|
public void | simpleRemoveFromCollectionChangeRecord(java.lang.Object referenceKey, java.lang.Object changeSetToRemove, oracle.toplink.essentials.internal.sessions.ObjectChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)ADVANCED:
This method is used to have an object removed from a collection once the
changeSet is applied. The referenceKey parameter should only be used for
direct Maps.
CollectionChangeRecord collectionChangeRecord = (CollectionChangeRecord)changeSet.getChangesForAttributeNamed(this.getAttributeName());
if (collectionChangeRecord == null) {
collectionChangeRecord = new CollectionChangeRecord(changeSet);
collectionChangeRecord.setAttribute(getAttributeName());
collectionChangeRecord.setMapping(this);
collectionChangeRecord.getRemoveObjectList().put(changeSetToRemove, changeSetToRemove);
changeSet.addChange(collectionChangeRecord);
} else {
getContainerPolicy().recordRemoveFromCollectionInChangeRecord((ObjectChangeSet)changeSetToRemove, collectionChangeRecord);
}
if (referenceKey != null){
((ObjectChangeSet)changeSetToRemove).setOldKey(referenceKey);
}
|
public void | updateChangeRecord(java.lang.Object clone, java.lang.Object newValue, java.lang.Object oldValue, oracle.toplink.essentials.internal.sessions.ObjectChangeSet objectChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)INTERNAL:
Either create a new change record or update with the new value. This is used
by attribute change tracking.
Specifically in a collection mapping this will be called when the customer
Set a new collection. In this case we will need to mark the change record
with the new and the old versions of the collection.
And mark the ObjectChangeSet with the attribute name then when the changes are calculated
force a compare on the collections to determine changes.
CollectionChangeRecord collectionChangeRecord = (CollectionChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
if (collectionChangeRecord == null) {
collectionChangeRecord = new CollectionChangeRecord(objectChangeSet);
collectionChangeRecord.setAttribute(getAttributeName());
collectionChangeRecord.setMapping(this);
objectChangeSet.addChange(collectionChangeRecord);
}
if (collectionChangeRecord.getOriginalCollection() == null){
collectionChangeRecord.setOriginalCollection(oldValue);
}
collectionChangeRecord.setLatestCollection(newValue);
objectChangeSet.deferredDetectionRequiredOn(getAttributeName());
|
public void | useCollectionClass(java.lang.Class concreteClass)PUBLIC:
Configure the mapping to use an instance of the specified container class
to hold the target objects.
The container class must implement (directly or indirectly) the
java.util.Collection interface.
ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass, hasOrderBy());
setContainerPolicy(policy);
|
public void | useMapClass(java.lang.Class concreteClass, java.lang.String keyName)PUBLIC:
Configure the mapping to use an instance of the specified container
clas to hold the target objects. The key used to index a value in the
Map is the value returned by either a call to a
specified zero-argument method or the value of a field.
To facilitate resolving the keyName to a method or field,
the mapping's referenceClass must set before calling this method.
Note: If the keyName is for a method, that method must be implemented
by the class (or a superclass) of any value to be inserted into the
Map .
The container class must implement (directly or indirectly) the
java.util.Map interface.
// the reference class has to be specified before coming here
if (getReferenceClassName() == null) {
throw DescriptorException.referenceClassNotSpecified(this);
}
ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass);
policy.setKeyName(keyName, getReferenceClassName());
setContainerPolicy(policy);
|
public void | useMapClass(java.lang.Class concreteClass)PUBLIC:
Configure the mapping to use an instance of the specified container
class to hold the target objects. The key used to index a value in the
Map is an instance of the composite primary key class.
To facilitate resolving the primary key class, the mapping's
referenceClass must set before calling this method.
The container class must implement (directly or indirectly) the
java.util.Map interface.
useMapClass(concreteClass, null);
|
public void | useSortedSetClass(java.lang.Class concreteClass, java.util.Comparator comparator)PUBLIC:
Configure the mapping to use an instance of the specified container class
to hold the target objects.
The container class must implement (directly or indirectly) the
java.util.SortedSet interface.
try {
SortedCollectionContainerPolicy policy = (SortedCollectionContainerPolicy)ContainerPolicy.buildPolicyFor(concreteClass);
policy.setComparator(comparator);
setContainerPolicy(policy);
} catch (ClassCastException e) {
useCollectionClass(concreteClass);
}
|
public void | useTransparentCollection()PUBLIC:
If transparent indirection is used, a special collection will be placed in the source
object's attribute.
Fetching of the contents of the collection from the database will be delayed
until absolutely necessary. (Any message sent to the collection will cause
the contents to be faulted in from the database.)
This can result in rather significant performance gains, without having to change
the source object's attribute from Collection (or List or Vector) to
ValueHolderInterface.
setIndirectionPolicy(new TransparentIndirectionPolicy());
useCollectionClass(ClassConstants.IndirectList_Class);
|
public void | useTransparentList()PUBLIC:
If transparent indirection is used, a special collection will be placed in the source
object's attribute.
Fetching of the contents of the collection from the database will be delayed
until absolutely necessary. (Any message sent to the collection will cause
the contents to be faulted in from the database.)
This can result in rather significant performance gains, without having to change
the source object's attribute from List to
ValueHolderInterface.
setIndirectionPolicy(new TransparentIndirectionPolicy());
useCollectionClass(ClassConstants.IndirectList_Class);
|
public void | useTransparentMap(java.lang.String methodName)PUBLIC:
If transparent indirection is used, a special map will be placed in the source
object's attribute.
Fetching of the contents of the map from the database will be delayed
until absolutely necessary. (Any message sent to the map will cause
the contents to be faulted in from the database.)
This can result in rather significant performance gains, without having to change
the source object's attribute from Map (or Dictionary or Hashtable) to
ValueHolderInterface.
The key used in the Map is the value returned by a call to the zero parameter
method named methodName. The method should be a zero argument method implemented (or
inherited) by the value to be inserted into the Map.
setIndirectionPolicy(new TransparentIndirectionPolicy());
useMapClass(ClassConstants.IndirectMap_Class, methodName);
|
public void | useTransparentSet()PUBLIC:
If transparent indirection is used, a special collection will be placed in the source
object's attribute.
Fetching of the contents of the collection from the database will be delayed
until absolutely necessary. (Any message sent to the collection will cause
the contents to be faulted in from the database.)
This can result in rather significant performance gains, without having to change
the source object's attribute from Set to
ValueHolderInterface.
setIndirectionPolicy(new TransparentIndirectionPolicy());
useCollectionClass(IndirectSet.class);
|
public void | validateBeforeInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
To validate mappings declaration
super.validateBeforeInitialization(session);
getIndirectionPolicy().validateContainerPolicy(session.getIntegrityChecker());
if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
Class attributeType = ((InstanceVariableAttributeAccessor)getAttributeAccessor()).getAttributeType();
getIndirectionPolicy().validateDeclaredAttributeTypeForCollection(attributeType, session.getIntegrityChecker());
} else if (getAttributeAccessor() instanceof MethodAttributeAccessor) {
Class returnType = ((MethodAttributeAccessor)getAttributeAccessor()).getGetMethodReturnType();
getIndirectionPolicy().validateGetMethodReturnTypeForCollection(returnType, session.getIntegrityChecker());
Class parameterType = ((MethodAttributeAccessor)getAttributeAccessor()).getSetMethodParameterType();
getIndirectionPolicy().validateSetMethodParameterTypeForCollection(parameterType, session.getIntegrityChecker());
}
|
protected java.lang.Object | valueFromRowInternalWithJoin(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 field from the row or a value holder on the query to obtain the object.
To get here the mapping's isJoiningSupported() should return true,
currently that's the case for only 1-m and m-m.
// If the query was using joining, all of the result rows will have been set.
List rows = joinManager.getDataResults_();
Object value = getContainerPolicy().containerInstance();
// A nested query must be built to pass to the descriptor that looks like the real query execution would,
// these should be cached on the query during prepare.
ObjectLevelReadQuery nestedQuery = null;
if (joinManager.getJoinedMappingQueries_() != null) {
nestedQuery = (ObjectLevelReadQuery) joinManager.getJoinedMappingQueries_().get(this);
} else {
nestedQuery = prepareNestedJoins(joinManager, executionSession);
}
nestedQuery.setSession(executionSession);
//CR #4365 - used to prevent infinite recursion on refresh object cascade all
nestedQuery.setQueryId(joinManager.getBaseQuery().getQueryId());
// Extract the primary key of the source object, to filter only the joined rows for that object.
Vector sourceKey = getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(row, executionSession);
CacheKey sourceCacheKey = new CacheKey(sourceKey);
// A set of target cache keys must be maintained to avoid duplicates from multiple 1-m joins.
Set targetCacheKeys = new HashSet();
// For each rows, extract the target row and build the target object and add to the collection.
for (int index = 0; index < rows.size(); index++) {
AbstractRecord sourceRow = (AbstractRecord)rows.get(index);
AbstractRecord targetRow = sourceRow;
// Row will be set to null if part of another object's join already processed.
if (targetRow != null) {
// 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.
targetRow = trimRowForJoin(targetRow, joinManager, executionSession);
AbstractRecord pkRow = trimRowForJoin(sourceRow, new Integer(joinManager.getParentResultIndex()), executionSession);
nestedQuery.setTranslationRow(targetRow);
// Extract the primary key of the row to filter only the joined rows for the source object.
Vector rowSourceKey = getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(pkRow, executionSession);
if(rowSourceKey != null) {
CacheKey rowSourceCacheKey = new CacheKey(rowSourceKey);
// Only build/add the object if the join row is for the object.
if (sourceCacheKey.equals(rowSourceCacheKey)) {
// Partial object queries must select the primary key of the source and related objects.
// If the target joined rows in null (outerjoin) means an empty collection.
Vector targetKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(targetRow, executionSession);
if (targetKey == null) {
// A null primary key means an empty collection returned as nulls from an outerjoin.
return getIndirectionPolicy().valueFromRow(value);
}
CacheKey targetCacheKey = new CacheKey(targetKey);
// Only build/add the taregt object once, skip duplicates from multiple 1-m joins.
if (!targetCacheKeys.contains(targetCacheKey)) {
targetCacheKeys.add(targetCacheKey);
Object targetObject = getReferenceDescriptor().getObjectBuilder().buildObject(nestedQuery, targetRow, nestedQuery.getJoinedAttributeManager());
nestedQuery.setTranslationRow(null);
getContainerPolicy().addInto(targetObject, value, executionSession);
}
}
} else {
// Clear an empty row
rows.set(index, null);
}
}
}
return getIndirectionPolicy().valueFromRow(value);
|
public boolean | verifyDelete(java.lang.Object object, oracle.toplink.essentials.internal.sessions.AbstractSession session)INTERNAL:
Checks if object is deleted from the database or not.
// Row is built for translation
if (isReadOnly()) {
return true;
}
if (isPrivateOwned()) {
Object objects = getRealCollectionAttributeValueFromObject(object, session);
ContainerPolicy containerPolicy = getContainerPolicy();
for (Object iter = containerPolicy.iteratorFor(objects); containerPolicy.hasNext(iter);) {
if (!session.verifyDelete(containerPolicy.next(iter, session))) {
return false;
}
}
}
AbstractRecord row = getDescriptor().getObjectBuilder().buildRowForTranslation(object, session);
//cr 3819 added the line below to fix the translationtable to ensure that it
// contains the required values
prepareTranslationRow(row, object, session);
Object value = session.executeQuery(getSelectionQuery(), row);
return getContainerPolicy().isEmpty(value);
|