use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectChangeSet method getOldValue.
public Object getOldValue(AbstractSession session) {
if (this.isNew) {
return null;
}
if (this.changes == null || this.changes.isEmpty()) {
// object has not changed
return this.cloneObject;
} else {
if (this.cloneObject != null && session != null) {
Object oldValue = this.descriptor.getObjectBuilder().buildNewInstance();
FetchGroup fetchGroup = null;
FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
if (fetchGroupManager != null) {
fetchGroup = fetchGroupManager.getObjectFetchGroup(this.cloneObject);
}
for (DatabaseMapping mapping : this.descriptor.getMappings()) {
String attributeName = mapping.getAttributeName();
if (fetchGroup == null || fetchGroup.containsAttributeInternal(attributeName)) {
ChangeRecord changeRecord = (ChangeRecord) getChangesForAttributeNamed(attributeName);
if (changeRecord != null) {
mapping.setRealAttributeValueInObject(oldValue, changeRecord.getOldValue());
} else {
mapping.setAttributeValueInObject(oldValue, mapping.getAttributeValueFromObject(this.cloneObject));
}
}
}
return oldValue;
}
}
return null;
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method buildBackupClone.
/**
* Returns the backup clone of the specified object. This is called only from unit of work.
* The clone sent as parameter is always a working copy from the unit of work.
*/
public Object buildBackupClone(Object clone, UnitOfWorkImpl unitOfWork) {
// The copy policy builds clone .
ClassDescriptor descriptor = this.descriptor;
Object backup = descriptor.getCopyPolicy().buildClone(clone, unitOfWork);
// PERF: Avoid synchronized enumerator as is concurrency bottleneck.
List<DatabaseMapping> mappings = getCloningMappings();
int size = mappings.size();
if (descriptor.hasFetchGroupManager() && descriptor.getFetchGroupManager().isPartialObject(clone)) {
FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
for (int index = 0; index < size; index++) {
DatabaseMapping mapping = mappings.get(index);
if (fetchGroupManager.isAttributeFetched(clone, mapping.getAttributeName())) {
mapping.buildBackupClone(clone, backup, unitOfWork);
}
}
} else {
for (int index = 0; index < size; index++) {
mappings.get(index).buildBackupClone(clone, backup, unitOfWork);
}
}
return backup;
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method copyObject.
/**
* Return a copy of the object.
* This is NOT used for unit of work but for templatizing an object.
* The depth and primary key reseting are passed in.
*/
public Object copyObject(Object original, CopyGroup copyGroup) {
Object copy = copyGroup.getCopies().get(original);
if (copyGroup.shouldCascadeTree()) {
FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
if (fetchGroupManager != null) {
// empty copy group means all the attributes should be copied - don't alter it.
if (copyGroup.hasItems()) {
// by default add primary key attribute(s) if not already in the group
if (!copyGroup.shouldResetPrimaryKey()) {
for (DatabaseMapping mapping : this.primaryKeyMappings) {
String name = mapping.getAttributeName();
if (!copyGroup.containsAttributeInternal(name)) {
copyGroup.addAttribute(name);
}
}
} else {
for (DatabaseMapping mapping : this.primaryKeyMappings) {
if (mapping.isForeignReferenceMapping()) {
String name = mapping.getAttributeName();
if (!copyGroup.containsAttributeInternal(name)) {
copyGroup.addAttribute(name);
}
}
}
}
// by default version attribute if not already in the group
if (!copyGroup.shouldResetVersion()) {
if (this.lockAttribute != null) {
if (!copyGroup.containsAttributeInternal(this.lockAttribute)) {
copyGroup.addAttribute(this.lockAttribute);
}
}
}
FetchGroup fetchGroup = fetchGroupManager.getObjectFetchGroup(original);
if (fetchGroup != null) {
if (!fetchGroup.getAttributeNames().containsAll(copyGroup.getAttributeNames())) {
// trigger fetch group if it does not contain all attributes of the copy group.
fetchGroup.onUnfetchedAttribute((FetchGroupTracker) original, null);
}
}
}
// Entity fetch group currently set on copyObject
EntityFetchGroup existingEntityFetchGroup = null;
if (copy != null) {
Object[] copyArray = (Object[]) copy;
// copy of the original
copy = copyArray[0];
// A set of CopyGroups that have visited.
Set<CopyGroup> visitedCopyGroups = (Set<CopyGroup>) copyArray[1];
if (visitedCopyGroups.contains(copyGroup)) {
// original has been already visited with this copyGroup - leave
return copy;
} else {
visitedCopyGroups.add(copyGroup);
}
existingEntityFetchGroup = fetchGroupManager.getObjectEntityFetchGroup(copy);
}
// Entity fetch group that will be assigned to copyObject
EntityFetchGroup newEntityFetchGroup = null;
// Attributes to be visited - only reference mappings will be visited.
// If null then all attributes should be visited.
Set<String> attributesToVisit = copyGroup.getAttributeNames();
// Attributes to be copied
Set<String> attributesToCopy = attributesToVisit;
boolean shouldCopyAllAttributes = false;
boolean shouldAssignNewEntityFetchGroup = false;
if (copy != null && existingEntityFetchGroup == null) {
// all attributes have been already copied
attributesToCopy = null;
} else {
// Entity fetch group corresponding to copyPolicy.
// Note that empty, or null, or containing all arguments attributesToCopy
// results in copyGroupFetchGroup = null;
EntityFetchGroup copyGroupEntityFetchGroup = fetchGroupManager.getEntityFetchGroup(attributesToCopy);
if (copyGroupEntityFetchGroup == null) {
// all attributes will be copied
shouldCopyAllAttributes = true;
}
if (copy != null) {
if (copyGroupEntityFetchGroup != null) {
if (!copyGroup.shouldResetPrimaryKey()) {
if (!existingEntityFetchGroup.getAttributeNames().containsAll(attributesToCopy)) {
// Entity fetch group that will be assigned to copy object
newEntityFetchGroup = fetchGroupManager.flatUnionFetchGroups(existingEntityFetchGroup, copyGroupEntityFetchGroup, false);
shouldAssignNewEntityFetchGroup = true;
}
}
attributesToCopy = new HashSet(attributesToCopy);
attributesToCopy.removeAll(existingEntityFetchGroup.getAttributeNames());
}
} else {
// copy does not exist - create it
copy = copyGroup.getSession().getDescriptor(original).getObjectBuilder().buildNewInstance();
Set<CopyGroup> visitedCopyGroups = new HashSet();
visitedCopyGroups.add(copyGroup);
copyGroup.getCopies().put(original, new Object[] { copy, visitedCopyGroups });
if (!copyGroup.shouldResetPrimaryKey()) {
newEntityFetchGroup = copyGroupEntityFetchGroup;
shouldAssignNewEntityFetchGroup = true;
}
}
}
if (shouldAssignNewEntityFetchGroup) {
fetchGroupManager.setObjectFetchGroup(copy, newEntityFetchGroup, null);
}
for (DatabaseMapping mapping : getDescriptor().getMappings()) {
String name = mapping.getAttributeName();
boolean shouldCopy = shouldCopyAllAttributes || (attributesToCopy != null && attributesToCopy.contains(name));
boolean shouldVisit = attributesToVisit == null || attributesToVisit.contains(name);
if (shouldCopy || shouldVisit) {
boolean isVisiting = false;
// unless it's a reference mapping pass copyGroup - just to carry the session.
CopyGroup mappingCopyGroup = copyGroup;
if (mapping.isForeignReferenceMapping()) {
ForeignReferenceMapping frMapping = (ForeignReferenceMapping) mapping;
ClassDescriptor referenceDescriptor = frMapping.getReferenceDescriptor();
if (referenceDescriptor != null) {
isVisiting = true;
mappingCopyGroup = copyGroup.getGroup(name);
if (mappingCopyGroup == null) {
FetchGroupManager referenceFetchGroupManager = referenceDescriptor.getFetchGroupManager();
if (referenceFetchGroupManager != null) {
EntityFetchGroup nonReferenceEntityFetchGroup = referenceFetchGroupManager.getNonReferenceEntityFetchGroup(copyGroup.shouldResetPrimaryKey(), copyGroup.shouldResetVersion());
if (nonReferenceEntityFetchGroup != null) {
mappingCopyGroup = nonReferenceEntityFetchGroup.toCopyGroup();
} else {
// null nonReferenceEntityFetchGroup is equivalent to containing all attributes:
// create a new empty CopyGroup.
mappingCopyGroup = new CopyGroup();
mappingCopyGroup.shouldCascadeTree();
}
} else {
// TODO: would that work?
mappingCopyGroup = new CopyGroup();
mappingCopyGroup.dontCascade();
isVisiting = false;
}
mappingCopyGroup.setCopies(copyGroup.getCopies());
mappingCopyGroup.setShouldResetPrimaryKey(copyGroup.shouldResetPrimaryKey());
mappingCopyGroup.setShouldResetVersion(copyGroup.shouldResetVersion());
}
mappingCopyGroup.setSession(copyGroup.getSession());
}
} else if (mapping.isAggregateObjectMapping()) {
mappingCopyGroup = new CopyGroup();
}
if (shouldCopy || isVisiting) {
// TODO: optimization: (even when isVisiting == true) redefine buildCopy to take shouldCopy and don't copy if not required.
mapping.buildCopy(copy, original, mappingCopyGroup);
}
}
}
} else {
// fetchGroupManager == null
// TODO
}
} else {
// ! copyGroup.shouldCascadeTree()
if (copy != null) {
return copy;
}
copy = instantiateClone(original, copyGroup.getSession());
copyGroup.getCopies().put(original, copy);
// PERF: Avoid synchronized enumerator as is concurrency bottleneck.
List<DatabaseMapping> mappings = getCloningMappings();
int size = mappings.size();
for (int index = 0; index < size; index++) {
mappings.get(index).buildCopy(copy, original, copyGroup);
}
if (copyGroup.shouldResetPrimaryKey() && (!(this.descriptor.isDescriptorTypeAggregate()))) {
// Do not reset if any of the keys is mapped through a 1-1, i.e. back reference id has already changed.
boolean hasOneToOne = false;
List<DatabaseMapping> primaryKeyMappings = getPrimaryKeyMappings();
size = primaryKeyMappings.size();
for (int index = 0; index < size; index++) {
if (primaryKeyMappings.get(index).isOneToOneMapping()) {
hasOneToOne = true;
}
}
if (!hasOneToOne) {
for (int index = 0; index < size; index++) {
DatabaseMapping mapping = primaryKeyMappings.get(index);
// Only null out direct mappings, as others will be nulled in the respective objects.
if (mapping.isAbstractColumnMapping()) {
Object nullValue = ((AbstractColumnMapping) mapping).getObjectValue(null, copyGroup.getSession());
mapping.setAttributeValueInObject(copy, nullValue);
} else if (mapping.isTransformationMapping()) {
mapping.setAttributeValueInObject(copy, null);
}
}
}
}
// PERF: Avoid events if no listeners.
if (this.descriptor.getEventManager().hasAnyEventListeners()) {
org.eclipse.persistence.descriptors.DescriptorEvent event = new org.eclipse.persistence.descriptors.DescriptorEvent(copy);
event.setSession(copyGroup.getSession());
event.setOriginalObject(original);
event.setEventCode(DescriptorEventManager.PostCloneEvent);
this.descriptor.getEventManager().executeEvent(event);
}
}
return copy;
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class WriteLockManager method traverseRelatedLocks.
/**
* INTERNAL:
* Traverse the object and acquire locks on all related objects.
*/
public CacheKey traverseRelatedLocks(Object objectForClone, Map lockedObjects, Map refreshedObjects, ClassDescriptor descriptor, AbstractSession cloningSession) {
// If all mappings have indirection short-circuit.
if (descriptor.shouldAcquireCascadedLocks()) {
FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
boolean isPartialObject = (fetchGroupManager != null) && fetchGroupManager.isPartialObject(objectForClone);
for (Iterator<DatabaseMapping> mappings = descriptor.getLockableMappings().iterator(); mappings.hasNext(); ) {
DatabaseMapping mapping = mappings.next();
// Only cascade fetched mappings.
if (!isPartialObject || (fetchGroupManager.isAttributeFetched(objectForClone, mapping.getAttributeName()))) {
// any mapping in this list must not have indirection.
Object objectToLock = mapping.getAttributeValueFromObject(objectForClone);
if (mapping.isCollectionMapping()) {
// Ignore null, means empty.
if (objectToLock != null) {
ContainerPolicy cp = mapping.getContainerPolicy();
Object iterator = cp.iteratorFor(objectToLock);
while (cp.hasNext(iterator)) {
Object object = cp.next(iterator, cloningSession);
if (mapping.getReferenceDescriptor().hasWrapperPolicy()) {
object = mapping.getReferenceDescriptor().getWrapperPolicy().unwrapObject(object, cloningSession);
}
CacheKey toWaitOn = checkAndLockObject(object, lockedObjects, refreshedObjects, mapping, cloningSession);
if (toWaitOn != null) {
return toWaitOn;
}
}
}
} else {
if (mapping.getReferenceDescriptor().hasWrapperPolicy()) {
objectToLock = mapping.getReferenceDescriptor().getWrapperPolicy().unwrapObject(objectToLock, cloningSession);
}
CacheKey toWaitOn = checkAndLockObject(objectToLock, lockedObjects, refreshedObjects, mapping, cloningSession);
if (toWaitOn != null) {
return toWaitOn;
}
}
}
}
}
return null;
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class AdvancedFetchGroupJunitTest method testVerifyFetchGroups.
public void testVerifyFetchGroups() {
if (isWeavingEnabled()) {
ClassDescriptor hockeyGearDescriptor = getServerSession().getDescriptor(HockeyGear.class);
FetchGroupManager hockeyGearFetchGroupManager = hockeyGearDescriptor.getFetchGroupManager();
assertTrue("Wrong number of fetch groups for HockeyGear", hockeyGearFetchGroupManager.getFetchGroups().size() == 1);
assertNotNull("The 'MSRP' fetch group was not found for HockeyGear", hockeyGearFetchGroupManager.getFetchGroup("MSRP"));
ClassDescriptor padsDescriptor = getServerSession().getDescriptor(Pads.class);
FetchGroupManager padsFetchGroupManager = padsDescriptor.getFetchGroupManager();
assertTrue("Wrong number of fetch groups for Pads", padsFetchGroupManager.getFetchGroups().size() == 3);
assertNotNull("The 'HeightAndWidth' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("HeightAndWidth"));
assertNotNull("The 'Weight' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("Weight"));
assertNotNull("The 'AgeGroup' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("AgeGroup"));
ClassDescriptor chestProtectorDescriptor = getServerSession().getDescriptor(ChestProtector.class);
FetchGroupManager chestProtectorFetchGroupManager = chestProtectorDescriptor.getFetchGroupManager();
assertTrue("Wrong number of fetch groups for ChestProtector", chestProtectorFetchGroupManager.getFetchGroups().size() == 1);
assertNotNull("The 'AgeGroup' fetch group was not found for ChestProtector", chestProtectorFetchGroupManager.getFetchGroup("AgeGroup"));
}
}
Aggregations