use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class OneToManyMapping method preDelete.
/**
* INTERNAL:
* Delete the reference objects.
*/
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
if (!shouldObjectModifyCascadeToParts(query)) {
if (this.listOrderField != null) {
updateTargetRowPreDeleteSource(query);
}
return;
}
AbstractSession session = query.getSession();
// else delete everything in one shot.
if (mustDeleteReferenceObjectsOneByOne()) {
Object objects = getRealCollectionAttributeValueFromObject(query.getObject(), session);
ContainerPolicy cp = getContainerPolicy();
if (this.isCascadeOnDeleteSetOnDatabase && session.isUnitOfWork()) {
for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
Object wrappedObject = cp.nextEntry(iterator, session);
Object object = cp.unwrapIteratorResult(wrappedObject);
((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(object);
}
}
int cascade = query.getCascadePolicy();
for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
Object wrappedObject = cp.nextEntry(iterator, session);
Object object = cp.unwrapIteratorResult(wrappedObject);
// PERF: Avoid query execution if already deleted.
if (!session.getCommitManager().isCommitCompletedInPostOrIgnore(object) || this.containerPolicy.propagatesEventsToCollection()) {
if (session.isUnitOfWork() && ((UnitOfWorkImpl) session).isObjectNew(object)) {
session.getCommitManager().markIgnoreCommit(object);
} else {
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setIsExecutionClone(true);
deleteQuery.setObject(object);
deleteQuery.setCascadePolicy(cascade);
session.executeQuery(deleteQuery);
this.containerPolicy.propogatePreDelete(deleteQuery, wrappedObject);
}
}
}
if (!session.isUnitOfWork()) {
// This deletes any objects on the database, as the collection in memory may have been changed.
// This is not required for unit of work, as the update would have already deleted these objects,
// and the backup copy will include the same objects causing double deletes.
deleteReferenceObjectsLeftOnDatabase(query);
}
} else {
deleteAll(query, session);
}
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class DirectMapMapping method iterateOnElement.
/**
* INTERNAL:
* Iterate on the specified element.
*/
@Override
public void iterateOnElement(DescriptorIterator iterator, Object element) {
super.iterateOnElement(iterator, element);
ContainerPolicy cp = getContainerPolicy();
for (Object iter = cp.iteratorFor(element); cp.hasNext(iter); ) {
Object wrappedObject = cp.nextEntry(iter, iterator.getSession());
cp.iterateOnMapKey(iterator, wrappedObject);
}
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class DirectMapMapping method valueFromRowInternalWithJoin.
/**
* INTERNAL:
* Return the value of the field from the row or a value holder on the query to obtain the object.
*/
@Override
protected Object valueFromRowInternalWithJoin(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey parentCacheKey, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
ContainerPolicy policy = getContainerPolicy();
Object value = policy.containerInstance();
ObjectBuilder objectBuilder = getDescriptor().getObjectBuilder();
// Extract the primary key of the source object, to filter only the joined rows for that object.
Object sourceKey = objectBuilder.extractPrimaryKeyFromRow(row, executionSession);
// If the query was using joining, all of the result rows by primary key will have been computed.
List<AbstractRecord> rows = joinManager.getDataResultsByPrimaryKey().get(sourceKey);
// this can occur with pagination where the last row may not be complete.
if (rows == null) {
return valueFromRowInternal(row, joinManager, sourceQuery, executionSession);
}
// A set of direct values must be maintained to avoid duplicates from multiple 1-m joins.
Set directValues = new HashSet();
Converter valueConverter = getValueConverter();
// For each rows, extract the target row and build the target object and add to the collection.
int size = rows.size();
for (int index = 0; index < size; index++) {
AbstractRecord sourceRow = rows.get(index);
AbstractRecord targetRow = sourceRow;
// 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);
// 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.
Object directKey = this.containerPolicy.buildKeyFromJoinedRow(targetRow, joinManager, sourceQuery, parentCacheKey, executionSession, isTargetProtected);
if (directKey == null) {
// A null direct value means an empty collection returned as nulls from an outerjoin.
return getIndirectionPolicy().valueFromRow(value);
}
// Only build/add the target object once, skip duplicates from multiple 1-m joins.
if (!directValues.contains(directKey)) {
directValues.add(directKey);
Object directValue = targetRow.get(this.directField);
// Allow for value conversion.
if (valueConverter != null) {
directValue = valueConverter.convertDataValueToObjectValue(directValue, executionSession);
}
policy.addInto(directKey, directValue, value, executionSession);
}
}
return getIndirectionPolicy().valueFromRow(value);
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class ParameterExpression method validateParameterValueAgainstMapping.
/**
* INTERNAL
* Validate the passed parameter against the local base mapping.
* Throw a QueryException if the parameter is of an incorrect class for object comparison.
* Added for Bug 245268
*/
protected void validateParameterValueAgainstMapping(Object value, boolean useBaseExpression) {
Expression queryKey = null;
if (useBaseExpression) {
// used to support validating against the base expression in the case of nesting
ParameterExpression baseExpression = (ParameterExpression) getBaseExpression();
queryKey = baseExpression.getLocalBase();
} else {
// used where we need to simply validate against the local base expression
queryKey = this.getLocalBase();
}
if ((value != null) && !(value instanceof Collection) && (queryKey != null) && queryKey.isObjectExpression()) {
DatabaseMapping mapping = ((ObjectExpression) queryKey).getMapping();
if (mapping != null) {
if (mapping.isCollectionMapping() && queryKey.isMapEntryExpression() && !((MapEntryExpression) queryKey).shouldReturnMapEntry()) {
// this is a map key expression, operate on the key
ContainerPolicy cp = mapping.getContainerPolicy();
Object keyType = cp.getKeyType();
Class<?> keyTypeClass = keyType instanceof Class<?> ? (Class) keyType : ((ClassDescriptor) keyType).getJavaClass();
if (!keyTypeClass.isInstance(value)) {
throw QueryException.incorrectClassForObjectComparison(baseExpression, value, mapping);
}
} else if (mapping.isDirectCollectionMapping()) {
// Do not validate direct collection, as type may be convertable.
} else if (mapping.isForeignReferenceMapping() && !mapping.getReferenceDescriptor().getJavaClass().isInstance(value)) {
throw QueryException.incorrectClassForObjectComparison(baseExpression, value, mapping);
}
}
}
}
use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.
the class AggregateCollectionMapping method mergeIntoObject.
/**
* INTERNAL:
* Merge changes from the source to the target object.
*/
@Override
public void mergeIntoObject(Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
return;
}
if (isTargetUnInitialized) {
// This will happen if the target object was removed from the cache before the commit was attempted
if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiatedOrChanged(source))) {
setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
return;
}
}
if (!shouldMergeCascadeReference(mergeManager)) {
// This is only going to happen on mergeClone, and we should not attempt to merge the reference
return;
}
if (mergeManager.shouldRefreshRemoteObject() && shouldMergeCascadeParts(mergeManager) && usesIndirection()) {
mergeRemoteValueHolder(target, source, mergeManager);
return;
}
if (mergeManager.isForRefresh()) {
if (!isAttributeValueInstantiatedOrChanged(target)) {
// the refresh that attribute
return;
}
} else if (!isAttributeValueInstantiatedOrChanged(source)) {
// modified
return;
}
ContainerPolicy containerPolicy = getContainerPolicy();
Object valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
Object valueOfTarget = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
for (Object sourceValuesIterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(sourceValuesIterator); ) {
Object wrappedSourceValue = containerPolicy.nextEntry(sourceValuesIterator, mergeManager.getSession());
Object sourceValue = containerPolicy.unwrapIteratorResult(wrappedSourceValue);
// For some odd reason support for having null in the collection was added. This does not make sense...
Object originalValue = null;
if (sourceValue != null) {
// CR#2896 - TW
originalValue = getReferenceDescriptor(sourceValue.getClass(), mergeManager.getSession()).getObjectBuilder().buildNewInstance();
getReferenceDescriptor(sourceValue.getClass(), mergeManager.getSession()).getObjectBuilder().mergeIntoObject(originalValue, true, sourceValue, mergeManager, targetSession);
containerPolicy.addInto(containerPolicy.keyFromIterator(sourceValuesIterator), originalValue, 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);
}
Aggregations