use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method revertFetchGroupData.
/**
* Clean up the cached object data and only revert the fetch group data back to the cached object.
*/
private void revertFetchGroupData(Object domainObject, ClassDescriptor concreteDescriptor, CacheKey cacheKey, ObjectBuildingQuery query, JoinedAttributeManager joinManager, AbstractRecord databaseRow, AbstractSession session, boolean targetIsProtected) {
FetchGroup fetchGroup = query.getExecutionFetchGroup(concreteDescriptor);
FetchGroupManager fetchGroupManager = concreteDescriptor.getFetchGroupManager();
// the cached object is either invalidated, or staled as the version is newer, or a refresh is explicitly set on the query.
// clean all data of the cache object.
fetchGroupManager.reset(domainObject);
// set fetch group reference to the cached object
fetchGroupManager.setObjectFetchGroup(domainObject, fetchGroupManager.getEntityFetchGroup(fetchGroup), session);
// Bug 276362 - set the CacheKey's read time (to re-validate the CacheKey) before buildAttributesIntoObject is called
cacheKey.setReadTime(query.getExecutionTime());
// read in the fetch group data only
concreteDescriptor.getObjectBuilder().buildAttributesIntoObject(domainObject, cacheKey, databaseRow, query, joinManager, fetchGroup, false, session);
// set refresh on fetch group
fetchGroupManager.setRefreshOnFetchGroupToObject(domainObject, (query.shouldRefreshIdentityMapResult() || concreteDescriptor.shouldAlwaysRefreshCache()));
// set query id to prevent infinite recursion on refresh object cascade all
cacheKey.setLastUpdatedQueryId(query.getQueryId());
// register the object into the IM and set the write lock object if applied.
if (concreteDescriptor.usesOptimisticLocking()) {
OptimisticLockingPolicy policy = concreteDescriptor.getOptimisticLockingPolicy();
cacheKey.setWriteLockValue(policy.getValueToPutInCache(databaseRow, session));
}
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class QueryKeyExpression method valuesFromCollection.
/**
* INTERNAL
* This method iterates through a collection and gets the values from the objects to conform in an in-memory query.
*/
public Object valuesFromCollection(Object object, AbstractSession session, int valueHolderPolicy, boolean isObjectUnregistered) {
// in case the mapping is null - this can happen if a query key is being used
// In this case, check for the query key and find it's mapping.
boolean readMappingFromQueryKey = false;
if (getMapping() == null) {
getMappingFromQueryKey();
readMappingFromQueryKey = true;
}
// For bug 2780817 get the mapping directly from the object. In EJB 2.0
// inheritance, each child must override mappings defined in an abstract
// class with its own.
DatabaseMapping mapping = this.mapping;
ClassDescriptor descriptor = mapping.getDescriptor();
if (descriptor.hasInheritance() && (descriptor.getJavaClass() != object.getClass())) {
descriptor = descriptor.getInheritancePolicy().getDescriptor(object.getClass());
mapping = descriptor.getObjectBuilder().getMappingForAttributeName(mapping.getAttributeName());
}
// fetch group support
if (descriptor.hasFetchGroupManager()) {
FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
if (fetchGroupManager.isPartialObject(object) && (!fetchGroupManager.isAttributeFetched(object, mapping.getAttributeName()))) {
// the conforming attribute is not fetched, simply throw exception
throw QueryException.cannotConformUnfetchedAttribute(mapping.getAttributeName());
}
}
if (mapping.isAbstractColumnMapping()) {
return mapping.valueFromObject(object, mapping.getField(), session);
} else if (mapping.isForeignReferenceMapping()) {
// CR 3677 integration of a ValueHolderPolicy
Object valueFromMapping = mapping.getAttributeValueFromObject(object);
if (!((ForeignReferenceMapping) mapping).getIndirectionPolicy().objectIsInstantiated(valueFromMapping)) {
if (valueHolderPolicy != InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION) {
// you should instantiate the valueholder for this to work
throw QueryException.mustInstantiateValueholders();
}
// maybe we should throw this exception from the start, to save time
}
Object valueToIterate = mapping.getRealAttributeValueFromObject(object, session);
UnitOfWorkImpl uow = isObjectUnregistered ? (UnitOfWorkImpl) session : null;
// }
if (mapping.isCollectionMapping() && (valueToIterate != null)) {
// For bug 2766379 must use the correct version of vectorFor to
// unwrap the result same time.
valueToIterate = mapping.getContainerPolicy().vectorFor(valueToIterate, session);
// registered objects.
if (isObjectUnregistered && (uow.getCloneMapping().get(object) == null)) {
Vector objectValues = (Vector) valueToIterate;
for (int i = 0; i < objectValues.size(); i++) {
Object original = objectValues.elementAt(i);
Object clone = uow.getIdentityMapAccessorInstance().getIdentityMapManager().getFromIdentityMap(original);
if (clone != null) {
objectValues.setElementAt(clone, i);
}
}
}
// For CR 2612601, conforming without registering, a query could be
// bob.get("address").get("city").equal("Ottawa"); where the address
// has been registered and modified in the UOW, but bob has not. Thus
// even though bob does not point to the modified address now, it will
// as soon as it is registered, so should point to it here.
} else if (isObjectUnregistered && (uow.getCloneMapping().get(object) == null)) {
Object clone = uow.getIdentityMapAccessorInstance().getIdentityMapManager().getFromIdentityMap(valueToIterate);
if (clone != null) {
valueToIterate = clone;
}
}
return valueToIterate;
} else if (mapping.isAggregateMapping()) {
Object aggregateValue = mapping.getAttributeValueFromObject(object);
// Bug 3995468 - if this query key is to a mapping in an aggregate object, get the object from actual mapping rather than the aggregate mapping
while (readMappingFromQueryKey && mapping.isAggregateObjectMapping() && !((AggregateObjectMapping) mapping).getReferenceClass().equals(queryKey.getDescriptor().getJavaClass())) {
mapping = mapping.getReferenceDescriptor().getObjectBuilder().getMappingForField(((DirectQueryKey) queryKey).getField());
aggregateValue = mapping.getRealAttributeValueFromObject(aggregateValue, session);
}
return aggregateValue;
} else {
throw QueryException.cannotConformExpression();
}
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class AggregateObjectMapping method initializeReferenceDescriptor.
/**
* INTERNAL:
* Initialize the cloned reference descriptor with table names and primary keys
*/
protected void initializeReferenceDescriptor(ClassDescriptor clonedDescriptor, AbstractSession session) {
if (aggregateKeyTable != null) {
clonedDescriptor.setDefaultTable(aggregateKeyTable);
Vector<DatabaseTable> tables = new Vector<>(1);
tables.add(aggregateKeyTable);
clonedDescriptor.setTables(tables);
} else {
// Must ensure default tables remains the same.
clonedDescriptor.setDefaultTable(getDescriptor().getDefaultTable());
clonedDescriptor.setTables(getDescriptor().getTables());
clonedDescriptor.setPrimaryKeyFields(getDescriptor().getPrimaryKeyFields());
// We need to translate the mappings field now BEFORE the clonedDescriptor gets initialized.
// During clonedDescriptor initialize, the mappings will be initialized and the field needs translated by then.
// If we wait any longer, the initialized mapping will be set as a primary key if the field name matches primaryKeyFields
Vector<DatabaseMapping> mappingsToTranslate = clonedDescriptor.getMappings();
for (DatabaseMapping mapping : mappingsToTranslate) {
DatabaseField field = mapping.getField();
if (field != null) {
DatabaseField sourceField = getAggregateToSourceFields().get(field.getName());
translateField(sourceField, field, clonedDescriptor);
}
}
if (clonedDescriptor.hasTargetForeignKeyMapping(session) && !isJPAIdNested(session)) {
for (DatabaseField pkField : getDescriptor().getPrimaryKeyFields()) {
if (!getAggregateToSourceFields().containsKey(pkField.getName())) {
// pk field from the source descriptor will have its type set by source descriptor
// this only could be done if there is no aggregate field with the same name as pk field.
clonedDescriptor.getObjectBuilder().getFieldsMap().put(pkField, pkField);
}
}
}
}
if (this.getDescriptor().hasFetchGroupManager() && FetchGroupTracker.class.isAssignableFrom(clonedDescriptor.getJavaClass())) {
if (clonedDescriptor.getFetchGroupManager() == null) {
clonedDescriptor.setFetchGroupManager(new FetchGroupManager());
}
}
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectChangeTrackingPolicy method clearChanges.
/**
* INTERNAL:
* Clear the changes in the ObjectChangeListener
*/
@Override
public void clearChanges(Object clone, UnitOfWorkImpl uow, ClassDescriptor descriptor, boolean forRefresh) {
ObjectChangeListener listener = (ObjectChangeListener) ((ChangeTracker) clone)._persistence_getPropertyChangeListener();
if (listener != null) {
listener.clearChanges(forRefresh);
} else {
listener = (ObjectChangeListener) setChangeListener(clone, uow, descriptor);
}
ObjectBuilder builder = descriptor.getObjectBuilder();
// Only relationship mappings need to be reset.
if (!builder.isSimple()) {
dissableEventProcessing(clone);
// Must also ensure the listener has been set on collections and aggregates.
FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
boolean isPartialObject = (fetchGroupManager != null) && fetchGroupManager.isPartialObject(clone);
List<DatabaseMapping> mappings = builder.getRelationshipMappings();
int size = mappings.size();
// Only cascade fetched mappings.
for (int index = 0; index < size; index++) {
DatabaseMapping mapping = mappings.get(index);
if (!isPartialObject || fetchGroupManager.isAttributeFetched(clone, mapping.getAttributeName())) {
mapping.setChangeListener(clone, listener, uow);
}
}
enableEventProcessing(clone);
}
}
use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.
the class ObjectLevelReadQuery method prepareFetchGroup.
/**
* INTERNAL:
* Add mandatory attributes to fetch group, create entityFetchGroup.
*/
public void prepareFetchGroup() throws QueryException {
FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
if (fetchGroupManager != null) {
if (this.fetchGroup == null) {
if (this.fetchGroupName != null) {
this.fetchGroup = fetchGroupManager.getFetchGroup(this.fetchGroupName);
} else if (this.shouldUseDefaultFetchGroup) {
this.fetchGroup = this.descriptor.getFetchGroupManager().getDefaultFetchGroup();
}
}
if (this.fetchGroup != null) {
if (hasPartialAttributeExpressions()) {
// fetch group does not work with partial attribute reading
throw QueryException.fetchGroupNotSupportOnPartialAttributeReading();
}
// currently SOP is incompatible with fetch groups
setShouldUseSerializedObjectPolicy(false);
this.descriptor.getFetchGroupManager().prepareAndVerify(this.fetchGroup);
}
} else {
// FetchGroupManager is null
if (this.fetchGroup != null || this.fetchGroupName != null) {
throw QueryException.fetchGroupValidOnlyIfFetchGroupManagerInDescriptor(getDescriptor().getJavaClassName(), getName());
}
}
}
Aggregations