if (isReadOnly()) { return; objects = getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); if (this.containerPolicy.isEmpty(objects)) { return; prepareTranslationRow(query.getTranslationRow(), query.getObject(), query.getDescriptor(), query.getSession()); for (int index = 0; index < getReferenceKeyFields().size(); index++) { DatabaseField referenceKey = getReferenceKeyFields().get(index); DatabaseField sourceKey = getSourceKeyFields().get(index); Object sourceKeyValue = query.getTranslationRow().get(sourceKey); databaseRow.put(referenceKey, sourceKeyValue); while (this.containerPolicy.hasNext(keyIter)) { Map.Entry entry = (Map.Entry)this.containerPolicy.nextEntry(keyIter, query.getSession()); Object value = getFieldValue(entry.getValue(), query.getSession()); databaseRow.put(getDirectField(), value); ContainerPolicy.copyMapDataToRow(getContainerPolicy().getKeyMappingDataForWriteQuery(entry, query.getSession()), databaseRow); event[1] = getInsertQuery(); event[2] = databaseRow.clone(); query.getSession().getCommitManager().addDataModificationEvent(this, event); } else { query.getSession().executeQuery(getInsertQuery(), databaseRow); getContainerPolicy().propogatePostInsert(query, entry);
/** * INTERNAL: * Add or removes a new value and its change set to the collection change record based on the event passed in. This is used by * attribute change tracking. */ @Override public void updateCollectionChangeRecord(CollectionChangeEvent event, ObjectChangeSet changeSet, UnitOfWorkImpl uow) { if (event != null ) { //Letting the mapping create and add the ChangeSet to the ChangeRecord rather // than the policy, since the policy doesn't know how to handle DirectCollectionChangeRecord. // if ordering is to be supported in the future, check how the method in CollectionMapping is implemented Object key = null; if (event.getClass().equals(ClassConstants.MapChangeEvent_Class)){ key = ((MapChangeEvent)event).getKey(); } if (event.getChangeType() == CollectionChangeEvent.ADD) { addToCollectionChangeRecord(key, event.getNewValue(), changeSet, uow); } else if (event.getChangeType() == CollectionChangeEvent.REMOVE) { removeFromCollectionChangeRecord(key, event.getNewValue(), changeSet, uow); } else { throw ValidationException.wrongCollectionChangeEventType(event.getChangeType()); } } }
Object backUpAttribute = null; cloneAttribute = getAttributeValueFromObject(clone); if ((cloneAttribute != null) && (!getIndirectionPolicy().objectIsInstantiated(cloneAttribute))) { return null; Map cloneObjectCollection = (Map)getRealCollectionAttributeValueFromObject(clone, session); backUpAttribute = getAttributeValueFromObject(backUp); if ((backUpAttribute == null) && (cloneAttribute == null)) { return null; backUpCollection = (Map)getRealCollectionAttributeValueFromObject(backUp, session); changeRecord.setAttribute(getAttributeName()); changeRecord.setMapping(this); compareCollectionsForChange(backUpCollection, cloneObjectCollection, changeRecord, session); if (changeRecord.hasChanges()) { changeRecord.setOriginalCollection(backUpCollection);
/** * Initialize insert query. This query is used to insert the collection of objects into the * reference table. */ @Override protected void initializeInsertQuery(AbstractSession session) { super.initializeInsertQuery(session); getContainerPolicy().addFieldsForMapKey(getInsertQuery().getModifyRow()); }
ContainerPolicy policy = getContainerPolicy(); Object value = policy.containerInstance(); ObjectBuilder objectBuilder = getDescriptor().getObjectBuilder(); Converter keyConverter = getKeyConverter(); Converter valueConverter = getValueConverter(); targetRow = trimRowForJoin(targetRow, joinManager, executionSession); Object directKey = getContainerPolicy().buildKeyFromJoinedRow(targetRow, joinManager, sourceQuery, executionSession); if (directKey == null) { return getIndirectionPolicy().valueFromRow(value); Object directValue = targetRow.get(getDirectField()); return getIndirectionPolicy().valueFromRow(value);
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 (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) { setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession)); return; if (!shouldMergeCascadeReference(mergeManager)) { if (mergeManager.shouldRefreshRemoteObject() && usesIndirection()) { mergeRemoteValueHolder(target, source, mergeManager); return; if (!isAttributeValueInstantiated(target)) { } else if (!isAttributeValueInstantiated(source)) { Map valueOfSource = (Map)getRealCollectionAttributeValueFromObject(source, mergeManager.getSession()); Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession()); Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource)); if ((this.getDescriptor().getObjectChangePolicy().isObjectChangeTrackingPolicy()) && (target instanceof ChangeTracker) && (((ChangeTracker)target)._persistence_getPropertyChangeListener() != null)) { fireChangeEvents = true; while (containerPolicy.hasNext(iterator)) { Map.Entry entry = (Map.Entry)containerPolicy.nextEntry(iterator, mergeManager.getSession());
protected void postUpdateWithChangeSet(WriteObjectQuery writeQuery) throws DatabaseException { ObjectChangeSet changeSet = writeQuery.getObjectChangeSet(); DirectMapChangeRecord changeRecord = (DirectMapChangeRecord)changeSet.getChangesForAttributeNamed(this.getAttributeName()); if (changeRecord == null) { return; for (int index = 0; index < getReferenceKeyFields().size(); index++) { DatabaseField referenceKey = getReferenceKeyFields().get(index); DatabaseField sourceKey = getSourceKeyFields().get(index); Object sourceKeyValue = writeQuery.getTranslationRow().get(sourceKey); writeQuery.getTranslationRow().put(referenceKey, sourceKeyValue); event[1] = getDeleteQuery(); event[2] = thisRow; writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event); AbstractRecord thisRow = writeQuery.getTranslationRow().clone(); Object value = changeRecord.getAddObjects().get(entry.getKey()); value = getFieldValue(value, writeQuery.getSession()); ContainerPolicy.copyMapDataToRow(this.containerPolicy.getKeyMappingDataForWriteQuery(entry, writeQuery.getSession()), thisRow); thisRow.add(getDirectField(), value); event[1] = getInsertQuery(); event[2] = thisRow; writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
protected void initializeDeleteQuery(AbstractSession session) { if (!getDeleteQuery().hasSessionName()) { getDeleteQuery().setSessionName(session.getName()); if (hasCustomDeleteQuery()) { return; List<DatabaseField> identityFields = getContainerPolicy().getIdentityFieldsForMapKey(); Iterator<DatabaseField> i = identityFields.iterator(); while (i.hasNext()){ for (int index = 0; index < getReferenceKeyFields().size(); index++) { DatabaseField referenceKey = getReferenceKeyFields().get(index); DatabaseField sourceKey = getSourceKeyFields().get(index); statement.setTable(getReferenceTable()); getDeleteQuery().setSQLStatement(statement);
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(); return valueFromRowInternal(row, joinManager, sourceQuery, executionSession); Converter valueConverter = getValueConverter(); targetRow = trimRowForJoin(targetRow, joinManager, executionSession); if (directKey == null) { return getIndirectionPolicy().valueFromRow(value); return getIndirectionPolicy().valueFromRow(value);
ContainerPolicy mappingContainerPolicy = getContainerPolicy(); synchronized (query) { referenceDataByKey = (Hashtable)query.getProperty("batched objects"); mappingContainerPolicy = getContainerPolicy(); if (referenceDataByKey == null) { Object referenceKey = null; if (query.isObjectBuildingQuery()){ referenceKey = getDirectMapUsableContainerPolicy().buildKey(databaseRow, (ObjectBuildingQuery)query, session); } else { referenceKey = getDirectMapUsableContainerPolicy().buildKey(databaseRow, null, session); Object referenceValue = referenceRow.get(getDirectField()); CacheKey eachCacheKey = new CacheKey(extractKeyFromTargetRow(referenceRow, session)); if (getValueConverter() != null) { referenceValue = getValueConverter().convertDataValueToObjectValue(referenceValue, query.getSession()); Object result = referenceDataByKey.get(new CacheKey(extractPrimaryKeyFromRow(databaseRow, session)));
} else if (collectionMapping instanceof DirectMapMapping) { DirectMapMapping directMapMapping = (DirectMapMapping) collectionMapping; Vector<DatabaseField> sourceKeyFields = directMapMapping.getSourceKeyFields(); Vector<DatabaseField> referenceKeyFields = directMapMapping.getReferenceKeyFields(); directMapMapping.getReferenceTableName(), null, idColumnMapping, keyMapping(directMapMapping.getContainerPolicy().getIdentityFieldsForMapKey()), null, null,
@Override protected void initializeSelectionStatement(AbstractSession session) { if (this.selectionQuery.isReadAllQuery()){ ((ReadAllQuery)this.selectionQuery).addAdditionalField(getDirectField().clone()); } else { SQLSelectStatement statement = (SQLSelectStatement)this.selectionQuery.getSQLStatement(); statement.addTable(getReferenceTable()); statement.addField(getDirectField().clone()); getContainerPolicy().addAdditionalFieldsToQuery(this.selectionQuery, getAdditionalFieldsBaseExpression(this.selectionQuery)); statement.normalize(session, null); } if (this.selectionQuery.isDirectReadQuery()){ ((DirectReadQuery)this.selectionQuery).setResultType(DataReadQuery.MAP); } }
protected void initializeSelectionStatement(AbstractSession session) { if (selectionQuery.isReadAllQuery()){ ((ReadAllQuery)selectionQuery).addAdditionalField((DatabaseField)getDirectField().clone()); } else { SQLSelectStatement statement = (SQLSelectStatement)selectionQuery.getSQLStatement(); statement.addTable(getReferenceTable()); statement.addField((DatabaseField)getDirectField().clone()); getContainerPolicy().addAdditionalFieldsToQuery(selectionQuery, null); statement.normalize(session, null); } if (selectionQuery.isDirectReadQuery()){ ((DirectReadQuery)selectionQuery).setResultType(DataReadQuery.MAP); } }
/** * INTERNAL: * Propagate the preDelete event through the container policy if necessary */ public void preDelete(DeleteObjectQuery query) throws DatabaseException { if (getContainerPolicy().propagatesEventsToCollection()){ Object queryObject = query.getObject(); Object values = getAttributeValueFromObject(queryObject); Object iterator = containerPolicy.iteratorFor(values); while (containerPolicy.hasNext(iterator)){ Object wrappedObject = containerPolicy.nextEntry(iterator, query.getSession()); containerPolicy.propogatePreDelete(query, wrappedObject); } } super.preDelete(query); }
/** * INTERNAL: * Remove a value and its change set from the collection change record. This is used by * attribute change tracking. */ protected void removeFromCollectionChangeRecord(Object newKey, Object newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException { DirectMapChangeRecord collectionChangeRecord = (DirectMapChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName()); if (collectionChangeRecord == null) { collectionChangeRecord = new DirectMapChangeRecord(objectChangeSet); collectionChangeRecord.setAttribute(getAttributeName()); collectionChangeRecord.setMapping(this); objectChangeSet.addChange(collectionChangeRecord); } collectionChangeRecord.addRemoveChange(newKey, newValue); }
/** * 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); } }
/** * INTERNAL: * Cascade perform delete through mappings that require the cascade */ public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) { if (containerPolicy.isMappedKeyMapPolicy()){ Object values = getAttributeValueFromObject(object); Object iterator = containerPolicy.iteratorFor(values); while (containerPolicy.hasNext(iterator)){ Object wrappedObject = containerPolicy.nextEntry(iterator, uow); containerPolicy.cascadePerformRemoveIfRequired(wrappedObject, uow, visitedObjects); } } }
MappedKeyMapContainerPolicy mapContainerPolicy = getMappedKeyMapContainerPolicy(); for (AbstractRecord referenceRow : rows) { Object referenceKey = null; Object eachCacheKey = extractKeyFromTargetRow(referenceRow, 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. */ public void calculateDeferredChanges(ChangeRecord changeRecord, AbstractSession session) { DirectMapChangeRecord collectionRecord = (DirectMapChangeRecord)changeRecord; // TODO: Handle events that fired after collection was replaced. compareCollectionsForChange(collectionRecord.getOriginalCollection(), collectionRecord.getLatestCollection(), collectionRecord, session); }
/** * INTERNAL: * Require for cloning, the part must be cloned. * Ignore the objects, use the attribute value. */ @Override public Object buildCloneForPartObject(Object attributeValue, Object original, CacheKey cacheKey, Object clone, AbstractSession cloningSession, Integer refreshCascade, boolean isExisting, boolean isFromSharedCache) { if (attributeValue == null) { return containerPolicy.containerInstance(1); } 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 keysIterator = containerPolicy.iteratorFor(temporaryCollection); containerPolicy.hasNext(keysIterator);) { Map.Entry entry = (Map.Entry)containerPolicy.nextEntry(keysIterator, cloningSession); Object cloneKey = containerPolicy.buildCloneForKey(entry.getKey(), clone, cacheKey, null, cloningSession, isExisting, isFromSharedCache); Object cloneValue = buildElementClone(entry.getValue(), clone, cacheKey, refreshCascade, cloningSession, isExisting, isFromSharedCache); containerPolicy.addInto(cloneKey, cloneValue, clonedAttributeValue, cloningSession); } return clonedAttributeValue; }