/** * PUBLIC: * Define the target foreign key relationship in the one-to-many mapping. * This method is used for composite target foreign key relationships. * That is, the target object's table has multiple foreign key fields to * the source object's (typically primary) key fields. * Both the target foreign key field names and the corresponding source primary * key field names must be specified. */ public void setTargetForeignKeyFieldNames(String[] targetForeignKeyFieldNames, String[] sourceKeyFieldNames) { if (targetForeignKeyFieldNames.length != sourceKeyFieldNames.length) { throw DescriptorException.targetForeignKeysSizeMismatch(this); } for (int i = 0; i < targetForeignKeyFieldNames.length; i++) { this.addTargetForeignKeyFieldName(targetForeignKeyFieldNames[i], sourceKeyFieldNames[i]); } }
/** * INTERNAL: * Initialize the mapping. */ public void initialize(AbstractSession session) throws DescriptorException { super.initialize(session); if (!this.isSourceKeySpecified()) { // sourceKeyFields will be empty when #setTargetForeignKeyFieldName() is used this.setSourceKeyFields(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(getDescriptor().getPrimaryKeyFields())); } this.initializeTargetForeignKeysToSourceKeys(); if (this.shouldInitializeSelectionCriteria()) { this.setSelectionCriteria(this.buildDefaultSelectionCriteria()); } this.initializeDeleteAllQuery(); }
/** * INTERNAL: * Update the reference objects. */ public void postUpdate(WriteObjectQuery query) throws DatabaseException, OptimisticLockException { if (!this.shouldObjectModifyCascadeToParts(query)) { return; } // if the target objects are not instantiated, they could not have been changed.... if (!this.isAttributeValueInstantiated(query.getObject())) { return; } // manage objects added and removed from the collection Object objectsInMemory = this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); Object objectsInDB = this.readPrivateOwnedForObject(query); this.compareObjectsAndWrite(objectsInDB, objectsInMemory, query); }
/** * Initialize the delete all query. * This query is used to delete the collection of objects from the * database. */ protected void initializeDeleteAllQuery() { ((DeleteAllQuery)this.getDeleteAllQuery()).setReferenceClass(this.getReferenceClass()); if (!this.hasCustomDeleteAllQuery()) { // the selection criteria are re-used by the delete all query if (this.getSelectionCriteria() == null) { this.getDeleteAllQuery().setSelectionCriteria(this.buildDefaultSelectionCriteria()); } else { this.getDeleteAllQuery().setSelectionCriteria(this.getSelectionCriteria()); } } }
if (!this.shouldObjectModifyCascadeToPartsForPreDelete(query)) { return; if (this.mustDeleteReferenceObjectsOneByOne() || query.shouldCascadeOnlyDependentParts()) { Object objects = this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); ContainerPolicy cp = this.getContainerPolicy(); for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter);) { Object object = cp.next(iter, query.getSession()); if (shouldObjectDeleteCascadeToPart(query, object)) { DeleteObjectQuery deleteQuery = new DeleteObjectQuery(); deleteQuery.setObject(object); this.deleteReferenceObjectsLeftOnDatabase(query); this.deleteAll(query);
/** * Delete all the reference objects with a single query. */ protected void deleteAll(WriteObjectQuery query) throws DatabaseException { Object referenceObjects = null; if(usesIndirection()) { Object attribute = getAttributeAccessor().getAttributeValueFromObject(query.getObject()); if(attribute == null || (ClassConstants.IndirectContainer_Class.isAssignableFrom(attribute.getClass()) && !((IndirectContainer)attribute).isInstantiated())) { // An empty Vector indicates to DeleteAllQuery that no objects should be removed from cache referenceObjects = new Vector(0); } } if(referenceObjects == null) { referenceObjects = this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); } ((DeleteAllQuery)this.getDeleteAllQuery()).executeDeleteAll(query.getSession().getSessionForClass(this.getReferenceClass()), query.getTranslationRow(), this.getContainerPolicy().vectorFor(referenceObjects, query.getSession())); }
if (!this.shouldObjectModifyCascadeToParts(query)) { return; Object objects = this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); ContainerPolicy cp = this.getContainerPolicy(); for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter);) { Object object = cp.next(iter, query.getSession()); if (this.isPrivateOwned()) {
/** * INTERNAL: * Used to verify whether the specified object is deleted or not. */ public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException { if (this.isPrivateOwned()) { Object objects = this.getRealCollectionAttributeValueFromObject(object, session); ContainerPolicy containerPolicy = getContainerPolicy(); for (Object iter = containerPolicy.iteratorFor(objects); containerPolicy.hasNext(iter);) { if (!session.verifyDelete(containerPolicy.next(iter, session))) { return false; } } } return true; } }
/** * This method will make sure that all the records privately owned by this mapping are * actually removed. If such records are found then those are all read and removed one * by one along with their privately owned parts. */ protected void deleteReferenceObjectsLeftOnDatabase(WriteObjectQuery query) throws DatabaseException, OptimisticLockException { Object objects = this.readPrivateOwnedForObject(query); // Delete all these object one by one. ContainerPolicy cp = this.getContainerPolicy(); for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter);) { query.getSession().deleteObject(cp.next(iter, query.getSession())); } }
OneToManyMapping mapping = new OneToManyMapping(); process(mapping); mapping.addTargetForeignKeyField(fkField, keys.get(fkField));
/** * PUBLIC: * Define the target foreign key relationship in the one-to-many mapping. * This method is used for composite target foreign key relationships. * That is, the target object's table has multiple foreign key fields * that are references to * the source object's (typically primary) key fields. * Both the target foreign key field name and the corresponding * source primary key field name must be specified. * Because the target object's table must store a foreign key to the source table, * the target object must map that foreign key, this is normally done through a * one-to-one mapping back-reference. Other options include: * <ul> * <li> use a DirectToFieldMapping and maintain the * foreign key fields directly in the target * <li> use a ManyToManyMapping * <li> use an AggregateCollectionMapping * </ul> * @see DirectToFieldMapping * @see ManyToManyMapping * @see AggregateCollectionMapping */ public void addTargetForeignKeyFieldName(String targetForeignKeyFieldName, String sourceKeyFieldName) { this.addTargetForeignKeyField(new DatabaseField(targetForeignKeyFieldName), new DatabaseField(sourceKeyFieldName)); }