/** * PUBLIC: * Define the target foreign key relationship in the 1-1 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 primary key fields. * Both the target foreign key field and the source primary key field must * be specified. * The distinction between a foreign key and target foreign key is that the * 1-1 mapping will not populate the target foreign key value when written * (because it is in the target table). Normally 1-1's are through foreign * keys but in bi-directional 1-1's the back reference will be a target * foreign key. In obscure composite legacy data models a 1-1 may consist of * a foreign key part and a target foreign key part, in this case both * method will be called with the correct parts. */ public void addTargetForeignKeyField(DatabaseField targetForeignKeyField, DatabaseField sourcePrimaryKeyField) { getSourceToTargetKeyFields().put(sourcePrimaryKeyField, targetForeignKeyField); getTargetToSourceKeyFields().put(targetForeignKeyField, sourcePrimaryKeyField); }
/** * INTERNAL: * Return the primary key for the reference object (i.e. the object * object referenced by domainObject and specified by mapping). * This key will be used by a RemoteValueHolder. */ public Vector extractPrimaryKeysForReferenceObjectFromRow(AbstractRecord row) { List primaryKeyFields = getReferenceDescriptor().getPrimaryKeyFields(); Vector result = new Vector(primaryKeyFields.size()); for (int index = 0; index < primaryKeyFields.size(); index++) { DatabaseField targetKeyField = (DatabaseField)primaryKeyFields.get(index); DatabaseField sourceKeyField = (DatabaseField)getTargetToSourceKeyFields().get(targetKeyField); if (sourceKeyField == null) { return new Vector(1); } result.addElement(row.get(sourceKeyField)); } return result; }
/** * Return the appropriate hashtable that maps the "foreign keys" * to the "primary keys". */ protected Map getForeignKeysToPrimaryKeys() { if (this.isForeignKeyRelationship()) { return this.getSourceToTargetKeyFields(); } else { return this.getTargetToSourceKeyFields(); } }
/** * PUBLIC: * Define the target foreign key relationship in the 1-1 mapping. * This method is used for singleton target foreign key relationships only, * that is the target object's table has a foreign key field to * the source object's primary key field. * The target foreign key field name is specified. * The distinction between a foreign key and target foreign key is that the 1-1 * mapping will not populate the target foreign key value when written (because it is in the target table). * Normally 1-1's are through foreign keys but in bi-directional 1-1's * the back reference will be a target foreign key. */ public void setTargetForeignKeyFieldName(String targetForeignKeyFieldName) { DatabaseField targetField = new DatabaseField(targetForeignKeyFieldName); getTargetToSourceKeyFields().put(targetField, new DatabaseField()); }
/** * PUBLIC: * Define the foreign key relationship in the 1-1 mapping. * This method is used for composite foreign key relationships, * that is the source object's table has multiple foreign key fields to * the target object's primary key fields. * Both the source foreign key field and the target foreign key field must * be specified. * When a foreign key is specified TopLink will automatically populate the * value for that field from the target object when the object is written to * the database. If the foreign key is also mapped through a direct-to-field * then the direct-to-field must be set read-only. */ public void addForeignKeyField(DatabaseField sourceForeignKeyField, DatabaseField targetPrimaryKeyField) { setIsForeignKeyRelationship(true); getForeignKeyFields().addElement(sourceForeignKeyField); getSourceToTargetKeyFields().put(sourceForeignKeyField, targetPrimaryKeyField); getTargetToSourceKeyFields().put(targetPrimaryKeyField, sourceForeignKeyField); }
/** * INTERNAL: * The foreign keys primary keys are stored as database fields in the hashtable. */ protected void initializeForeignKeys(AbstractSession session) { Iterator sourceEnum = getSourceToTargetKeyFields().keySet().iterator(); Iterator targetEnum = getTargetToSourceKeyFields().keySet().iterator(); while (sourceEnum.hasNext()) { DatabaseField sourceField = (DatabaseField)sourceEnum.next(); DatabaseField targetField = (DatabaseField)targetEnum.next(); getDescriptor().buildField(sourceField); getReferenceDescriptor().buildField(targetField); } }
/** * INTERNAL: * Set a collection of the source to target field associations. */ public void setSourceToTargetKeyFieldAssociations(Vector sourceToTargetKeyFieldAssociations) { setSourceToTargetKeyFields(new HashMap(sourceToTargetKeyFieldAssociations.size() + 1)); setTargetToSourceKeyFields(new HashMap(sourceToTargetKeyFieldAssociations.size() + 1)); for (Enumeration associationsEnum = sourceToTargetKeyFieldAssociations.elements(); associationsEnum.hasMoreElements();) { Association association = (Association)associationsEnum.nextElement(); DatabaseField sourceField = new DatabaseField((String)association.getKey()); DatabaseField targetField = new DatabaseField((String)association.getValue()); getSourceToTargetKeyFields().put(sourceField, targetField); getTargetToSourceKeyFields().put(targetField, sourceField); } }
clone.setForeignKeyFields(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(getForeignKeyFields().size())); clone.setSourceToTargetKeyFields(new HashMap(getSourceToTargetKeyFields().size())); clone.setTargetToSourceKeyFields(new HashMap(getTargetToSourceKeyFields().size())); Hashtable setOfFields = new Hashtable(getTargetToSourceKeyFields().size()); for (Iterator targetEnum = getTargetToSourceKeyFields().keySet().iterator(); targetEnum.hasNext();) { DatabaseField targetField = (DatabaseField)targetEnum.next(); DatabaseField sourceField = (DatabaseField)getTargetToSourceKeyFields().get(targetField); setOfFields.put(sourceField, sourceClone); clone.getTargetToSourceKeyFields().put(targetClone, sourceClone);
getDescriptor().buildField(sourceField); getSourceToTargetKeyFields().put(sourceField, targetKeys.get(0)); getTargetToSourceKeyFields().put(targetKeys.get(0), sourceField); } else { if (getTargetToSourceKeyFields().size() != 1) { throw DescriptorException.foreignKeysDefinedIncorrectly(this); DatabaseField targetField = (DatabaseField)getTargetToSourceKeyFields().keySet().iterator().next(); getReferenceDescriptor().buildField(targetField); getTargetToSourceKeyFields().put(targetField, sourceKeys.get(0)); getSourceToTargetKeyFields().put(sourceKeys.get(0), targetField);
/** * INTERNAL: * Initialize the mapping. */ public void initialize(AbstractSession session) throws DescriptorException { super.initialize(session); // Must set table of foreign keys. for (Enumeration foreignKeysEnum = getForeignKeyFields().elements(); foreignKeysEnum.hasMoreElements();) { DatabaseField foreignKeyField = (DatabaseField)foreignKeysEnum.nextElement(); getDescriptor().buildField(foreignKeyField); } // If only a selection criteria is specified then the foreign keys do not have to be initialized. if (!(getTargetToSourceKeyFields().isEmpty() && getSourceToTargetKeyFields().isEmpty())) { if (getTargetToSourceKeyFields().isEmpty() || getSourceToTargetKeyFields().isEmpty()) { initializeForeignKeysWithDefaults(session); } else { initializeForeignKeys(session); } } if (shouldInitializeSelectionCriteria()) { initializeSelectionCriteria(session); } else { setShouldVerifyDelete(false); } setFields(collectFields()); }
/** * INTERNAL: * This method is for processing a single FieldResult, returning the DatabaseField it refers to. */ public DatabaseField processValueFromRecordForMapping(ClassDescriptor descriptor, String[] attributeNames, int currentLoc){ DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeNames[currentLoc]); if (mapping==null){throw QueryException.mappingForFieldResultNotFound(attributeNames,currentLoc);} currentLoc++; if (attributeNames.length!=currentLoc){ ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor(); DatabaseField df= processValueFromRecordForMapping(currentDescriptor, attributeNames, currentLoc); if (mapping.isOneToOneMapping()){ return (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(df)); } return df; }else{ //this is it.. return this mapping's field return (DatabaseField) mapping.getFields().firstElement(); } }
/** * INTERNAL: * This method is for processing all FieldResults for a mapping. Adds DatabaseFields to the passed in entityRecord */ public void getValueFromRecordForMapping(DatabaseRecord entityRecord,DatabaseMapping mapping, FieldResult fieldResult, DatabaseRecord databaseRecord){ ClassDescriptor currentDescriptor = mapping.getReferenceDescriptor(); /** check if this FieldResult contains any other FieldResults, process it if it doesn't */ if (fieldResult.getFieldResults()==null){ DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,fieldResult.getMultipleFieldIdentifiers(),1); /** If it is a 1:1 mapping we need to do the target to source field conversion. If it is an aggregate, it is fine as it is*/ if (mapping.isOneToOneMapping()){ dbfield = (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield)); } entityRecord.put(dbfield, databaseRecord.get(fieldResult.getColumnName())); return; } /** This processes each FieldResult stored in the collection of FieldResults individually */ Iterator fieldResults = fieldResult.getFieldResults().iterator(); while (fieldResults.hasNext()){ FieldResult tempFieldResult = ((FieldResult)fieldResults.next()); DatabaseField dbfield = processValueFromRecordForMapping(currentDescriptor,tempFieldResult.getMultipleFieldIdentifiers(),1); if (mapping.isOneToOneMapping()){ dbfield = (DatabaseField)(((OneToOneMapping)mapping).getTargetToSourceKeyFields().get(dbfield)); } entityRecord.put(dbfield, databaseRecord.get(tempFieldResult.getColumnName())); } }
/** * INTERNAL: * Process a @OneToOne or one-to-one element into a TopLink OneToOne * mapping. */ public void process() { // Initialize our mapping now with what we found. OneToOneMapping mapping = initOneToOneMapping(); if (getMappedBy().equals("")) { // Owning side, look for JoinColumns or PrimaryKeyJoinColumns. processOwningMappingKeys(mapping); } else { // Non-owning side, process the foreign keys from the owner. OneToOneMapping ownerMapping = null; if (getOwningMapping().isOneToOneMapping()){ ownerMapping = (OneToOneMapping)getOwningMapping(); } else { // If improper mapping encountered, throw an exception. getValidator().throwInvalidMappingEncountered(getJavaClass(), getReferenceClass()); } mapping.setSourceToTargetKeyFields(ownerMapping.getTargetToSourceKeyFields()); mapping.setTargetToSourceKeyFields(ownerMapping.getSourceToTargetKeyFields()); } // Add the mapping to the descriptor. m_descriptor.addMapping(mapping); } }