/** * PUBLIC: * Indicates whether the referenced object should always be joined on read queries. * Joining will join the two classes tables to read all of the data in a single query. * This should only be used if it is know that the related objects are always required with the source object, or indirection is not used. */ public void setUsesJoining(boolean usesJoining) { if (usesJoining == this.usesJoining) { return; } this.usesJoining = usesJoining; // For 3524579 now cache joined mappings on the object builder. // This allows a user to set joining dynamically after the // descriptors have been initialized. Generally this is not // supported, but since we were checking this flag in prepare after // initialization some degree of backward compatibility should be // provided. if (getDescriptor() != null) { getDescriptor().reInitializeJoinedAttributes(); } // Still every query which is already prepared, like all selection // queries, will not pick up this change. }
/** * Return the descriptor for whichever side of the * relation has the "primary key". */ protected ClassDescriptor getPrimaryKeyDescriptor() { if (this.isForeignKeyRelationship()) { return this.getReferenceDescriptor(); } else { return this.getDescriptor(); } }
/** * 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: * Extract the foreign key value from the source row. */ protected Vector extractForeignKeyFromRow(AbstractRecord row, AbstractSession session) { Vector key = new Vector(); for (Iterator fieldEnum = getSourceToTargetKeyFields().keySet().iterator(); fieldEnum.hasNext();) { DatabaseField field = (DatabaseField)fieldEnum.next(); Object value = row.get(field); // Must ensure the classificatin to get a cache hit. try { value = session.getDatasourcePlatform().getConversionManager().convertObject(value, getDescriptor().getObjectBuilder().getFieldClassification(field)); } catch (ConversionException e) { throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); } key.addElement(value); } return key; }
getDescriptor().buildField(sourceField); getSourceToTargetKeyFields().put(sourceField, targetKeys.get(0)); getTargetToSourceKeyFields().put(targetKeys.get(0), sourceField); throw DescriptorException.foreignKeysDefinedIncorrectly(this); List<DatabaseField> sourceKeys = getDescriptor().getPrimaryKeyFields(); if (sourceKeys.size() != 1) {
/** * 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: * Selection criteria is created with source foreign keys and target keys. */ protected void initializePrivateOwnedCriteria() { if (!isForeignKeyRelationship()) { setPrivateOwnedCriteria(getSelectionCriteria()); } else { Expression pkCriteria = getDescriptor().getObjectBuilder().getPrimaryKeyExpression(); ExpressionBuilder builder = new ExpressionBuilder(); Expression backRef = builder.getManualQueryKey(getAttributeName() + "-back-ref", getDescriptor()); Expression newPKCriteria = pkCriteria.rebuildOn(backRef); Expression twistedSelection = backRef.twist(getSelectionCriteria(), builder); if (getDescriptor().getQueryManager().getAdditionalJoinExpression() != null) { // We don't have to twist the additional join because it's all against the same node, which is our base // but we do have to rebuild it onto the manual query key Expression rebuiltAdditional = getDescriptor().getQueryManager().getAdditionalJoinExpression().rebuildOn(backRef); if (twistedSelection == null) { twistedSelection = rebuiltAdditional; } else { twistedSelection = twistedSelection.and(rebuiltAdditional); } } setPrivateOwnedCriteria(newPKCriteria.and(twistedSelection)); } }
/** * INTERNAL: * Get a value from the object and set that in the respective field of the row. */ public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) { // First check if the value can be obtained from the value holder's row. AbstractRecord referenceRow = getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object)); if (referenceRow != null) { Object value = referenceRow.get(field); // Must ensure the classification to get a cache hit. try { value = session.getDatasourcePlatform().convertObject(value, getFieldClassification(field)); } catch (ConversionException e) { throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); } return value; } Object referenceObject = getRealAttributeValueFromObject(object, session); if (referenceObject == null) { return null; } DatabaseField targetField = (DatabaseField)getSourceToTargetKeyFields().get(field); return getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(referenceObject, targetField, session); }
if (joinManager.isAttributeJoined(getDescriptor(), getAttributeName()) && joinManager.hasOuterJoinedAttributeQuery()) { Vector key = this.referenceDescriptor.getObjectBuilder().extractPrimaryKeyFromRow(targetRow, executionSession); if (key == null) {