Methods Summary |
---|
public void | addFetchGroup(oracle.toplink.essentials.queryframework.FetchGroup group)Add a named fetch group to the descriptor
//create a new fetch group and put it in the group map.
getFetchGroups().put(group.getName(), group);
|
public java.lang.Object | clone()INTERNAL:
Clone the fetch group manager
Object object = null;
try {
object = super.clone();
} catch (Exception exception) {
;
}
return object;
|
public void | copyFetchGroupInto(java.lang.Object source, java.lang.Object target)INTERNAL:
Copy fetch group refrerence from the source object to the target
if (isPartialObject(source)) {
((FetchGroupTracker)target).setFetchGroup(((FetchGroupTracker)source).getFetchGroup());
}
|
public oracle.toplink.essentials.descriptors.ClassDescriptor | getClassDescriptor()INTERNAL:
Return the referenced descriptor.
return getDescriptor();
|
public oracle.toplink.essentials.queryframework.FetchGroup | getDefaultFetchGroup()Return the descriptor-level default fetch group.
All read object and read all queries would use the default fetch group if no fetch group
is explicitly defined for the query, unless setShouldUseDefaultFetchGroup(false); is also
called on the query.
Default fetch group should be used carefully. It would be beneficial if most of the system queries
are for the subset of the object, so un-needed attributes data would not have to be read, and the
users do not have to setup every query for the given fetch group, as default one is always used.
However, if queries on object are mostly use case specific and not systematic, using default fetch group
could cause undesirable extra round-trip and performance degradation.
return defaultFetchGroup;
|
public oracle.toplink.essentials.descriptors.ClassDescriptor | getDescriptor()INTERNAL:
Return the referenced descriptor.
return descriptor;
|
public oracle.toplink.essentials.queryframework.FetchGroup | getFetchGroup(java.lang.String groupName)Return a pre-defined named fetch group.
return (FetchGroup)getFetchGroups().get(groupName);
|
public java.util.Map | getFetchGroups()Return the fetch group map: keyed by the group name, valued by the fetch group object.
if (fetchGroups == null) {
//lazy initialized
fetchGroups = new HashMap(2);
}
return fetchGroups;
|
public boolean | isAttributeFetched(java.lang.Object object, java.lang.String attributeName)Return true if the attribute of the object has already been fetched
FetchGroup fetchgroup = ((FetchGroupTracker)object).getFetchGroup();
return (fetchgroup == null) || (fetchgroup.getAttributes().contains(attributeName));
|
public boolean | isObjectValidForFetchGroup(java.lang.Object object, oracle.toplink.essentials.queryframework.FetchGroup fetchGroup)INTERNAL:
Return if the cached object data is sufficiently valid against a fetch group
FetchGroup groupInObject = ((FetchGroupTracker)object).getFetchGroup();
return (groupInObject == null) || groupInObject.isSupersetOf(fetchGroup);
|
public boolean | isPartialObject(java.lang.Object domainObject)INTERNAL:
Return true if the object is partially fetched and cached.
It applies to the query with fetch group.
if (domainObject != null) {
FetchGroup fetchGroupInCache = ((FetchGroupTracker)domainObject).getFetchGroup();
//if the fetch group reference is not null, it means the object is partial.
return (fetchGroupInCache != null);
}
return false;
|
public void | prepareQueryWithFetchGroup(oracle.toplink.essentials.queryframework.ObjectLevelReadQuery query)INTERNAL:
Prepare the query with the fetch group to add group attributes to the query
for partial reading.
//initialize query's fetch group
query.initializeFetchGroup();
if ((query.getFetchGroup() == null) || query.getFetchGroup().hasFetchGroupAttributeExpressions()) {
//simply return if fetch group is not defined; or if defined, it has been prepared already.
return;
} else {
if (query.isReportQuery()) {
//fetch group does not work with report query
throw QueryException.fetchGroupNotSupportOnReportQuery();
}
if (query.hasPartialAttributeExpressions()) {
//fetch group does not work with partial attribute reading
throw QueryException.fetchGroupNotSupportOnPartialAttributeReading();
}
}
Set attributes = query.getFetchGroup().getAttributes();
ObjectBuilder builder = query.getDescriptor().getObjectBuilder();
//First add all primary key attributes into the fetch group
Iterator pkMappingIter = builder.getPrimaryKeyMappings().iterator();
while (pkMappingIter.hasNext()) {
DatabaseMapping pkMapping = (DatabaseMapping)pkMappingIter.next();
DatabaseField pkField = pkMapping.getField();
// Add pk attribute to the fetch group attributes list
attributes.add(pkMapping.getAttributeName());
}
//second, add version/optimistic locking object attributes into the fetch group if applied.
OptimisticLockingPolicy lockingPolicy = getDescriptor().getOptimisticLockingPolicy();
if (query.shouldMaintainCache() && (lockingPolicy != null)) {
lockingPolicy.prepareFetchGroupForReadQuery(query.getFetchGroup(), query);
}
//thrid, prepare all fetch group attributes
Iterator attrIter = attributes.iterator();
while (attrIter.hasNext()) {
String attrName = (String)attrIter.next();
DatabaseMapping mapping = builder.getMappingForAttributeName(attrName);
if (mapping == null) {
//the attribute name defined in the fetch group is not mapped
throw QueryException.fetchGroupAttributeNotMapped(attrName);
}
//partially fetch each fetch group attribute
if (mapping.isCollectionMapping()) {
query.getFetchGroup().addFetchGroupAttribute(query.getExpressionBuilder().anyOf(attrName));
} else {
query.getFetchGroup().addFetchGroupAttribute(query.getExpressionBuilder().get(attrName));
}
}
|
private void | refreshFetchGroupIntoClones(java.lang.Object cachedObject, java.lang.Object workingClone, java.lang.Object backupClone, oracle.toplink.essentials.queryframework.FetchGroup fetchGroupInObject, oracle.toplink.essentials.queryframework.FetchGroup fetchGroupInClone, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)Refresh the fetch group data into the working and backup clones.
This is called if refresh is enforced
Vector mappings = descriptor.getMappings();
boolean isObjectPartial = (fetchGroupInObject != null);
Set fetchedAttributes = isObjectPartial ? fetchGroupInObject.getAttributes() : null;
for (int index = 0; index < mappings.size(); index++) {
DatabaseMapping mapping = (DatabaseMapping)mappings.get(index);
if ((!isObjectPartial) || ((fetchedAttributes != null) && fetchedAttributes.contains(mapping.getAttributeName()))) {
//only fill in the unfetched attributes into clones
mapping.buildClone(cachedObject, workingClone, uow, null);
mapping.buildClone(workingClone, backupClone, uow, null);
}
}
|
public void | reset(java.lang.Object source)INTERNAL:
Reset object attributes to the default values.
((FetchGroupTracker)source).resetFetchGroup();
|
private void | revertDataIntoUnfetchedAttributesOfClones(java.lang.Object cachedObject, java.lang.Object workingClone, java.lang.Object backupClone, oracle.toplink.essentials.queryframework.FetchGroup fetchGroupInObject, oracle.toplink.essentials.queryframework.FetchGroup fetchGroupInClone, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)Revert the clones' unfetched attributes, and leave fetched ones intact.
//if(fetchGroupInClone == null || fetchGroupInClone.isSupersetOf(fetchGroupInObject)) {
if (isObjectValidForFetchGroup(workingClone, fetchGroupInObject)) {
//if working clone is fully fetched or it's fetch group is superset of that of the cached object
//no reversion is needed, so simply return
return;
}
Vector mappings = descriptor.getMappings();
//fetched attributes list in working clone
Set fetchedAttributesClone = fetchGroupInClone.getAttributes();
for (int index = 0; index < mappings.size(); index++) {
DatabaseMapping mapping = (DatabaseMapping)mappings.get(index);
//only revert the attribute which is fetched by the cached object, but not fecthed by the clones.
if (isAttributeFetched(cachedObject, mapping.getAttributeName()) && (!fetchedAttributesClone.contains(mapping.getAttributeName()))) {
//only fill in the unfetched attributes into clones
mapping.buildClone(cachedObject, workingClone, uow, null);
mapping.buildClone(workingClone, backupClone, uow, null);
}
}
|
public void | setDefaultFetchGroup(oracle.toplink.essentials.queryframework.FetchGroup newDefaultFetchGroup)Set the descriptor-level default fetch group.
All read object and read all queries would use the default fetch group if no fetch group is
explicitly defined for the query, unless setShouldUseDefaultFetchGroup(false);
is also called on the query.
Default fetch group should be used carefully. It would be beneficial if most of the system queries
are for the subset of the object, so un-needed attributes data would not have to be read, and the
users do not have to setup every query for the given fetch group, as default one is always used.
However, if queries on object are mostly use case specific and not systematic, using default fetch group
could cause undesirable extra round-trip and performance degradation.
defaultFetchGroup = newDefaultFetchGroup;
|
public void | setDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor descriptor)Set the referenced descriptor.
this.descriptor = descriptor;
|
public void | setObjectFetchGroup(java.lang.Object source, oracle.toplink.essentials.queryframework.FetchGroup fetchGroup)INTERNAL:
Reset object attributes to the default their values.
if (descriptor.getFetchGroupManager() != null) {
((FetchGroupTracker)source).setFetchGroup(fetchGroup);
}
|
public void | setRefreshOnFetchGroupToObject(java.lang.Object source, boolean shouldRefreshOnFetchgroup)INTERNAL:
Set if the tracked object is fetched from executing a query with or without refresh.
((FetchGroupTracker)source).setShouldRefreshFetchGroup(shouldRefreshOnFetchgroup);
|
public boolean | shouldWriteInto(java.lang.Object cachedObject, java.lang.Object clone)INTERNAL:
Return true if the cached object data should be written in clone.
It is used in Fetch Group case when filling in the clone from the cached object.
if (isPartialObject(clone)) {
FetchGroup fetchGroupInSrc = ((FetchGroupTracker)cachedObject).getFetchGroup();
FetchGroup fetchGroupInTarg = ((FetchGroupTracker)clone).getFetchGroup();
//if the target fetch group is not null (i.e. fully fetched object) or if partially fetched, it's not a superset of that of the source,
//or if refresh is required, should always write (either refresh or revert) data from the cache to the clones.
return (!((fetchGroupInTarg == null) || fetchGroupInTarg.isSupersetOf(fetchGroupInSrc)) || ((FetchGroupTracker)cachedObject).shouldRefreshFetchGroup());
}
return false;
|
public void | unionFetchGroupIntoObject(java.lang.Object source, oracle.toplink.essentials.queryframework.FetchGroup newFetchGroup)INTERNAL:
Union the fetch group of the domain object with the new fetch group.
FetchGroupTracker tracker = (FetchGroupTracker)source;
tracker.setFetchGroup(unionFetchGroups(tracker.getFetchGroup(), newFetchGroup));
|
public oracle.toplink.essentials.queryframework.FetchGroup | unionFetchGroups(oracle.toplink.essentials.queryframework.FetchGroup first, oracle.toplink.essentials.queryframework.FetchGroup second)INTERNAL:
Union two fetch groups.
if ((first == null) || (second == null)) {
return null;
}
//return the superset if applied
if (first.isSupersetOf(second)) {
return first;
} else if (second.isSupersetOf(first)) {
return second;
}
//otherwise, union two fetch groups
StringBuffer unionGroupName = new StringBuffer(first.getName());
unionGroupName.append("_");
unionGroupName.append(second.getName());
FetchGroup unionFetchGroup = new FetchGroup(unionGroupName.toString());
unionFetchGroup.addAttributes(first.getAttributes());
unionFetchGroup.addAttributes(second.getAttributes());
return unionFetchGroup;
|
public void | writePartialIntoClones(java.lang.Object partialObject, java.lang.Object workingClone, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow)INTERNAL:
Write data of the partially fetched object into the working and backup clones
FetchGroup fetchGroupInClone = ((FetchGroupTracker)workingClone).getFetchGroup();
FetchGroup fetchGroupInObject = ((FetchGroupTracker)partialObject).getFetchGroup();
Object backupClone = uow.getBackupClone(workingClone);
//if refresh is set, force to fill in fecth group data
if (((FetchGroupTracker)partialObject).shouldRefreshFetchGroup()) {
//refresh and fill in the fecth group data
refreshFetchGroupIntoClones(partialObject, workingClone, backupClone, fetchGroupInObject, fetchGroupInClone, uow);
} else {//no refresh is enforced
//revert the unfetched attributes of the clones.
revertDataIntoUnfetchedAttributesOfClones(partialObject, workingClone, backupClone, fetchGroupInObject, fetchGroupInClone, uow);
}
//update fecth group in clone as the union of two
fetchGroupInObject = unionFetchGroups(fetchGroupInObject, fetchGroupInClone);
//finally, update clone's fetch group reference
setObjectFetchGroup(workingClone, fetchGroupInObject);
setObjectFetchGroup(backupClone, fetchGroupInObject);
|