/** INTERNAL: Print SQL onto the stream, using the ExpressionPrinter for context */ public void printSQL(ExpressionSQLPrinter printer) { if (isAttribute()) { printer.printField(getAliasedField()); } // If the mapping is a direct collection then this falls into a gray area. // It must be treated as an attribute at this moment for it has a direct field. // However it is not an attribute in the sense that it also represents a foreign // reference and a mapping criteria has been added. // For bug 2900974 these are now handled as non-attributes during normalize but // as attributes when printing SQL. // if ((!isAttribute()) && (getMapping() != null) && getMapping().isDirectCollectionMapping()) { DirectCollectionMapping directCollectionMapping = (DirectCollectionMapping) getMapping(); // The aliased table comes for free as it was a required part of the join criteria. TableExpression table = (TableExpression) getTable(directCollectionMapping.getReferenceTable()); DatabaseTable aliasedTable = table.aliasForTable(table.getTable()); DatabaseField aliasedField = (DatabaseField) directCollectionMapping.getDirectField().clone(); aliasedField.setTable(aliasedTable); printer.printField(aliasedField); } if ((getMapping() != null) && getMapping().isNestedTableMapping()) { DatabaseTable tableAlias = aliasForTable(new NestedTable(this)); printer.printString(tableAlias.getName()); } }
/** * INTERNAL: Returns the first field from each of the owned tables, used for fine-grained * pessimistic locking. */ protected Vector getForUpdateOfFields() { Vector allFields = getFields(); int expected = getTableAliases().size(); Vector firstFields = new Vector(expected); DatabaseTable lastTable = null; DatabaseField field = null; int i = 0; // The following loop takes O(n*m) time. n=# of fields. m=#tables. // However, in the m=1 case this will take one pass only. // Also assuming that fields are generally sorted by table, this will // take O(n) time. // An even faster way may be to go getDescriptor().getAdditionalPrimaryKeyFields. while ((i < allFields.size()) && (firstFields.size() < expected)) { field = (DatabaseField) allFields.elementAt(i++); if ((lastTable == null) || !field.getTable().equals(lastTable)) { lastTable = field.getTable(); int j = 0; while (j < firstFields.size()) { if (lastTable.equals(((DatabaseField) firstFields.elementAt(j)).getTable())) { break; } j++; } if (j == firstFields.size()) { firstFields.addElement(field); } } } return firstFields; }
/** * INTERNAL: This methods clones all the fields and ensures that each collection refers to the * same clones. */ @Override public Object clone() { VariableOneToOneMapping clone = (VariableOneToOneMapping) super.clone(); Map setOfKeys = new HashMap(getSourceToTargetQueryKeyNames().size()); Map sourceToTarget = new HashMap(getSourceToTargetQueryKeyNames().size()); Vector foreignKeys = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance( getForeignKeyFields().size()); if (getTypeField() != null) { clone.setTypeField((DatabaseField) this.getTypeField().clone()); } for (Iterator enumtr = getSourceToTargetQueryKeyNames().keySet().iterator(); enumtr.hasNext(); ) { // Clone the SourceKeyFields DatabaseField field = (DatabaseField) enumtr.next(); DatabaseField clonedField = (DatabaseField) field.clone(); setOfKeys.put(field, clonedField); // on the next line I'm cloning the query key names sourceToTarget.put(clonedField, getSourceToTargetQueryKeyNames().get(field)); } for (Enumeration enumtr = getForeignKeyFields().elements(); enumtr.hasMoreElements(); ) { DatabaseField field = (DatabaseField) enumtr.nextElement(); foreignKeys.addElement(setOfKeys.get(field)); } clone.setSourceToTargetQueryKeyFields(sourceToTarget); clone.setForeignKeyFields(foreignKeys); clone.setTypeIndicatorTranslation(new HashMap(this.getTypeIndicatorTranslation())); return clone; }
/** * INTERNAL: Return the classification for the field contained in the mapping. This is used to * convert the row value to a consistent java value. */ @Override public Class getFieldClassification(DatabaseField fieldToClassify) { if ((getTypeField() != null) && (fieldToClassify.equals(getTypeField()))) { return getTypeField().getType(); } String queryKey = (String) getSourceToTargetQueryKeyNames().get(fieldToClassify); if (queryKey == null) { return null; } // Search any of the implementor descriptors for a mapping for the query-key. Iterator iterator = getReferenceDescriptor().getInterfacePolicy().getChildDescriptors().iterator(); if (iterator.hasNext()) { ClassDescriptor firstChild = (ClassDescriptor) iterator.next(); DatabaseMapping mapping = firstChild.getObjectBuilder().getMappingForAttributeName(queryKey); if ((mapping != null) && (mapping.isDirectToFieldMapping())) { return ((AbstractDirectMapping) mapping).getAttributeClassification(); } QueryKey targetQueryKey = firstChild.getQueryKeyNamed(queryKey); if ((targetQueryKey != null) && (targetQueryKey.isDirectQueryKey())) { return firstChild .getObjectBuilder() .getFieldClassification(((DirectQueryKey) targetQueryKey).getField()); } } return null; }
/** INTERNAL: Alias the database field for our current environment */ protected void initializeAliasedField() { DatabaseField tempField = (DatabaseField) getField().clone(); DatabaseTable aliasedTable = getAliasedTable(); // Put in a special check here so that if the aliasing does nothing we don't cache the // result because it's invalid. This saves us from caching premature data if e.g. debugging // causes us to print too early" // if (aliasedTable.equals(getField().getTable())) { // return; // } else { aliasedField = tempField; aliasedField.setTable(aliasedTable); // } }