FileDocCategorySizeDatePackage
ClassDescriptor.javaAPI DocGlassfish v2 API144316Tue Jul 10 11:11:20 BST 2007oracle.toplink.essentials.descriptors

ClassDescriptor

public class ClassDescriptor extends Object implements Serializable, Cloneable

Purpose: Abstract descriptor class for defining persistence information on a class. This class provides the data independent behavior and is subclassed, for relational, object-relational, EIS, XML, etc.

see
RelationalDescriptor
see
oracle.toplink.essentials.objectrelational.ObjectRelationalDescriptor
see
oracle.toplink.essentials.eis.EISDescriptor
see
oracle.toplink.essentials.ox.XMLDescriptor

Fields Summary
protected Class
javaClass
protected String
javaClassName
protected Vector
tables
protected transient DatabaseTable
defaultTable
protected List
primaryKeyFields
protected transient Map
additionalTablePrimaryKeyFields
protected transient Vector
multipleTableInsertOrder
protected transient Map
multipleTableForeignKeys
protected transient Vector
fields
protected transient Vector
allFields
protected Vector
mappings
protected List
lockableMappings
protected Map
queryKeys
protected Class
identityMapClass
protected int
identityMapSize
protected String
sequenceNumberName
protected DatabaseField
sequenceNumberField
protected transient String
sessionName
protected boolean
shouldAlwaysRefreshCache
protected boolean
shouldOnlyRefreshCacheIfNewerVersion
protected boolean
shouldDisableCacheHits
protected transient Vector
constraintDependencies
protected transient String
amendmentMethodName
protected transient Class
amendmentClass
protected transient String
amendmentClassName
protected String
alias
protected boolean
shouldBeReadOnly
protected boolean
shouldAlwaysConformResultsInUnitOfWork
protected boolean
isIsolated
protected boolean
shouldRegisterResultsInUnitOfWork
protected DescriptorEventManager
eventManager
protected DescriptorQueryManager
queryManager
protected ObjectBuilder
objectBuilder
protected CopyPolicy
copyPolicy
protected InstantiationPolicy
instantiationPolicy
protected InheritancePolicy
inheritancePolicy
protected OptimisticLockingPolicy
optimisticLockingPolicy
protected Vector
cascadeLockingPolicies
protected WrapperPolicy
wrapperPolicy
protected ObjectChangePolicy
changePolicy
protected CMPPolicy
cmpPolicy
protected FetchGroupManager
fetchGroupManager
protected Map
properties
Additional properties may be added.
protected static final int
UNINITIALIZED
protected static final int
PREINITIALIZED
protected static final int
INITIALIZED
protected static final int
POST_INITIALIZED
protected static final int
ERROR
protected static final int
NORMAL
protected static final int
AGGREGATE
protected static final int
AGGREGATE_COLLECTION
protected transient int
initializationStage
protected int
descriptorType
protected boolean
shouldOrderMappings
protected CacheInvalidationPolicy
cacheInvalidationPolicy
protected boolean
shouldAcquireCascadedLocks
PERF: Used to optimize cache locking to only acquire deferred locks when required (no-indirection).
protected boolean
hasSimplePrimaryKey
PERF: Compute and store if the primary key is simple (direct-mapped) to allow fast extraction.
Constructors Summary
public ClassDescriptor()
PUBLIC: Return a new descriptor.


              
      
        // Properties
        this.tables = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(3);
        this.mappings = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
        this.primaryKeyFields = new ArrayList(2);
        this.fields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
        this.allFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
        this.constraintDependencies = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(2);
        this.multipleTableForeignKeys = new HashMap(5);
        this.queryKeys = new HashMap(5);
        this.initializationStage = UNINITIALIZED;
        this.shouldAlwaysRefreshCache = false;
        this.shouldOnlyRefreshCacheIfNewerVersion = false;
        this.shouldDisableCacheHits = false;
        this.identityMapSize = 100;
        this.identityMapClass = IdentityMap.getDefaultIdentityMapClass();
        this.descriptorType = NORMAL;
        this.shouldOrderMappings = true;
        this.shouldBeReadOnly = false;
        this.shouldAlwaysConformResultsInUnitOfWork = false;
        this.shouldAcquireCascadedLocks = false;
        this.hasSimplePrimaryKey = false;
        this.isIsolated = false;

        // Policies
        this.objectBuilder = new ObjectBuilder(this);
        setCopyPolicy(new InstantiationCopyPolicy());
        setInstantiationPolicy(new InstantiationPolicy());
        setEventManager(new oracle.toplink.essentials.descriptors.DescriptorEventManager());
        setQueryManager(new oracle.toplink.essentials.descriptors.DescriptorQueryManager());

        changePolicy = new DeferredChangeDetectionPolicy();
        this.cascadeLockingPolicies = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
    
Methods Summary
public voidaddAbstractQueryKey(java.lang.String queryKeyName)
PUBLIC: This method should only be used for interface descriptors. It adds an abstract query key to the interface descriptor. Any implementors of that interface must define the query key defined by this abstract query key.

        QueryKey queryKey = new QueryKey();
        queryKey.setName(queryKeyName);
        addQueryKey(queryKey);
    
public voidaddConstraintDependencies(java.lang.Class dependencies)
ADVANCED: TopLink automatically orders database access through the foreign key information provided in 1:1 and 1:m mappings. In some case when 1:1 are not defined it may be required to tell the descriptor about a constraint, this defines that this descriptor has a foreign key constraint to another class and must be inserted after instances of the other class.

        getConstraintDependencies().addElement(dependencies);
    
public oracle.toplink.essentials.mappings.DatabaseMappingaddDirectMapping(java.lang.String attributeName, java.lang.String fieldName)
PUBLIC: Add a direct mapping to the receiver. The new mapping specifies that an instance variable of the class of objects which the receiver describes maps in the default manner for its type to the indicated database field.

param
String instanceVariableName is the name of an instance variable of the class which the receiver describes.
param
String fieldName is the name of the database column which corresponds with the designated instance variable.
return
The newly created DatabaseMapping is returned.

        DirectToFieldMapping mapping = new DirectToFieldMapping();

        mapping.setAttributeName(attributeName);
        mapping.setFieldName(fieldName);

        return addMapping(mapping);
    
public oracle.toplink.essentials.mappings.DatabaseMappingaddDirectMapping(java.lang.String attributeName, java.lang.String getMethodName, java.lang.String setMethodName, java.lang.String fieldName)
PUBLIC: Add a direct mapping to the receiver. The new mapping specifies that a variable accessed by the get and set methods of the class of objects which the receiver describes maps in the default manner for its type to the indicated database field.

        DirectToFieldMapping mapping = new DirectToFieldMapping();

        mapping.setAttributeName(attributeName);
        mapping.setSetMethodName(setMethodName);
        mapping.setGetMethodName(getMethodName);
        mapping.setFieldName(fieldName);

        return addMapping(mapping);
    
public voidaddDirectQueryKey(java.lang.String queryKeyName, java.lang.String fieldName)
PUBLIC: Add a query key to the descriptor. Query keys define Java aliases to database fields.

        DirectQueryKey queryKey = new DirectQueryKey();
        DatabaseField field = new DatabaseField(fieldName);

        queryKey.setName(queryKeyName);
        queryKey.setField(field);
        getQueryKeys().put(queryKeyName, queryKey);
    
public oracle.toplink.essentials.mappings.DatabaseMappingaddMapping(oracle.toplink.essentials.mappings.DatabaseMapping mapping)
PUBLIC: Add a database mapping to the receiver. Perform any required initialization of both the mapping and the receiving descriptor as a result of adding the new mapping.

        // For CR#2646, if the mapping already points to the parent descriptor then leave it.
        if (mapping.getDescriptor() == null) {
            mapping.setDescriptor(this);
        }
        getMappings().addElement(mapping);
        return mapping;
    
public voidaddMultipleTableForeignKeyField(oracle.toplink.essentials.internal.helper.DatabaseField sourceField, oracle.toplink.essentials.internal.helper.DatabaseField targetField)
PUBLIC: This protocol can be used to associate multiple tables with foreign key information. The join criteria will be generated based on the fields provided. By default TopLink associates multiple tables using a primary key join where the primary keys fields are named the same.

  
        addMultipleTableForeignKeys(sourceField, targetField, true);  
    
public voidaddMultipleTableForeignKeyFieldName(java.lang.String sourceFieldName, java.lang.String targetFieldName)
PUBLIC: This protocol can be used to associate multiple tables with foreign key information. The join criteria will be generated based on the fields provided. By default TopLink associates multiple tables using a primary key join where the primary keys fields are named the same.

  
        addMultipleTableForeignKeyField(new DatabaseField(sourceFieldName), new DatabaseField(targetFieldName));  
    
protected voidaddMultipleTableForeignKeys(oracle.toplink.essentials.internal.helper.DatabaseField sourceField, oracle.toplink.essentials.internal.helper.DatabaseField targetField, boolean isForeignKey)
INTERNAL: Add the multiple fields, if is a foreign key then add the tables to the foreign keys ordering.

        
        // Make sure that the table is fully qualified.
        if ((!sourceField.hasTableName()) || (!targetField.hasTableName())) {
            throw DescriptorException.multipleTablePrimaryKeyMustBeFullyQualified(this);
        }
        
        DatabaseTable sourceTable = sourceField.getTable();
        DatabaseTable targetTable = targetField.getTable();
        setAdditionalTablePrimaryKeyFields(targetTable, sourceField, targetField);
        
        if (isForeignKey) {
            getMultipleTableForeignKeys().put(sourceTable, targetTable);
        } 
    
protected voidaddMultipleTableForeignKeys(java.lang.String fieldNameInSourceTable, java.lang.String fieldNameInTargetTable, boolean isForeignKey)
INTERNAL: Add the multiple table fields, if is a foreign key then add the tables to the foreign keys ordering.

        
        addMultipleTableForeignKeys(new DatabaseField(fieldNameInSourceTable), new DatabaseField(fieldNameInTargetTable), isForeignKey);
    
public voidaddMultipleTablePrimaryKeyField(oracle.toplink.essentials.internal.helper.DatabaseField sourceField, oracle.toplink.essentials.internal.helper.DatabaseField targetField)
PUBLIC: This protocol can be used to map the primary key fields in a multiple table descriptor. By default TopLink assumes that all of the primary key fields are named the same.

        addMultipleTableForeignKeys(sourceField, targetField, false);
    
public voidaddMultipleTablePrimaryKeyFieldName(java.lang.String sourceFieldName, java.lang.String targetFieldName)
PUBLIC: This protocol can be used to map the primary key field names in a multiple table descriptor. By default TopLink assumes that all of the primary key fields are named the same.

        addMultipleTablePrimaryKeyField(new DatabaseField(sourceFieldName), new DatabaseField(targetFieldName));
    
public voidaddPrimaryKeyField(oracle.toplink.essentials.internal.helper.DatabaseField field)
ADVANCED: Specify the primary key field of the descriptors table. This should be called for each field that makes up the primary key of the table. This can be used for advanced field types, such as XML nodes, or to set the field type.

        getPrimaryKeyFields().add(field);
    
public voidaddPrimaryKeyFieldName(java.lang.String fieldName)
PUBLIC: Specify the primary key field of the descriptors table. This should be called for each field that makes up the primary key of the table. If the descriptor has many tables, this must be the primary key in the first table, if the other tables have the same primary key nothing else is required, otherwise a primary key/foreign key field mapping must be provided for each of the other tables.

see
#addMultipleTableForeignKeyFieldName(String, String);

        getPrimaryKeyFields().add(new DatabaseField(fieldName));
    
public voidaddQueryKey(oracle.toplink.essentials.querykeys.QueryKey queryKey)
PUBLIC: Add a query key to the descriptor. Query keys define Java aliases to database fields.

        getQueryKeys().put(queryKey.getName(), queryKey);
    
public voidaddTable(oracle.toplink.essentials.internal.helper.DatabaseTable table)
PUBLIC: Specify the table for the class of objects the receiver describes. This method is used if there is more than one table.

        getTables().addElement(table);
    
public voidaddTableName(java.lang.String tableName)
PUBLIC: Specify the table name for the class of objects the receiver describes. If the table has a qualifier it should be specified using the dot notation, (i.e. "userid.employee"). This method is used if there is more than one table.

        addTable(new DatabaseTable(tableName));
    
public voidadjustMultipleTableInsertOrder()
INTERNAL: Adjust the order of the tables in the multipleTableInsertOrder Vector according to the FK relationship if one (or more) were previously specified. I.e. target of FK relationship should be inserted before source. If the multipleTableInsertOrder has been specified (presumably by the user) then do not change it.

        // Check if a user defined insert order was given.
        if ((getMultipleTableInsertOrder() == null) || getMultipleTableInsertOrder().isEmpty()) {
            setMultipleTableInsertOrder((Vector) getTables().clone());
            
            checkMultipleTableForeignKeys(false);
        } else {
            if (getMultipleTableInsertOrder().size() != getTables().size()) {
                throw DescriptorException.multipleTableInsertOrderMismatch(this);
            }
        
            checkMultipleTableForeignKeys(true);    
        }
    
public voidalwaysConformResultsInUnitOfWork()
PUBLIC: Used to set the descriptor to always conform in any unit of work query.

        setShouldAlwaysConformResultsInUnitOfWork(true);
    
public voidalwaysRefreshCache()
PUBLIC: This method is the equivalent of calling {@link #setShouldAlwaysRefreshCache} with an argument of true: it configures a Descriptor to always refresh the cache if data is received from the database by any query.

However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink will first look in the cache for the object. If the object is in the cache, the cached object is returned and data is not refreshed. To avoid cache hits, use the {@link #disableCacheHits} method.

Also note that the {@link oracle.toplink.essentials.sessions.UnitOfWork} will not refresh its registered objects.

Use this property with caution because it can lead to poor performance and may refresh on queries when it is not desired. Normally, if you require fresh data, it is better to configure a query with {@link oracle.toplink.essentials.queryframework.ObjectLevelReadQuery#refreshIdentityMapResult}. To ensure that refreshes are only done when required, use this method in conjunction with {@link #onlyRefreshCacheIfNewerVersion}.

see
#dontAlwaysRefreshCache

        setShouldAlwaysRefreshCache(true);
    
public voidapplyAmendmentMethod()
ADVANCED: Call the descriptor amendment method. This is called while loading or creating a descriptor that has an amendment method defined.

        applyAmendmentMethod(null);
    
public voidapplyAmendmentMethod(oracle.toplink.essentials.descriptors.DescriptorEvent event)
INTERNAL: Call the descriptor amendment method. This is called while loading or creating a descriptor that has an amendment method defined.

        if ((getAmendmentClass() == null) || (getAmendmentMethodName() == null)) {
            return;
        }

        Method method = null;
        Class[] argTypes = new Class[1];

        // BUG#2669585
        // Class argument type must be consistent, descriptor, i.e. instance may be a subclass.
        argTypes[0] = ClassDescriptor.class;
        try {
            method = Helper.getDeclaredMethod(getAmendmentClass(), getAmendmentMethodName(), argTypes);
        } catch (Exception ignore) {
            // Return type should now be ClassDescriptor.
            argTypes[0] = ClassDescriptor.class;
            try {
                method = Helper.getDeclaredMethod(getAmendmentClass(), getAmendmentMethodName(), argTypes);
            } catch (Exception exception) {
                throw DescriptorException.invalidAmendmentMethod(getAmendmentClass(), getAmendmentMethodName(), exception, this);
            }
        }

        Object[] args = new Object[1];
        args[0] = this;

        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    AccessController.doPrivileged(new PrivilegedMethodInvoker(method, null, args));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof IllegalAccessException) {
                        throw (IllegalAccessException)throwableException;
                    } else {
                        throw (InvocationTargetException)throwableException;
                    }
                }
            } else {
                PrivilegedAccessHelper.invokeMethod(method, null, args);
            }
        } catch (Exception exception) {
            throw DescriptorException.errorOccuredInAmendmentMethod(getAmendmentClass(), getAmendmentMethodName(), exception, this);
        }
    
public booleanarePrimaryKeyFields(java.util.Vector fields)
INTERNAL: Used to determine if a foreign key references the primary key.

        if (!(fields.size() == (getPrimaryKeyFields().size()))) {
            return false;
        }

        for (Enumeration enumFields = fields.elements(); enumFields.hasMoreElements();) {
            DatabaseField field = (DatabaseField)enumFields.nextElement();

            if (!getPrimaryKeyFields().contains(field)) {
                return false;
            }
        }

        return true;
    
public oracle.toplink.essentials.internal.databaseaccess.DatabaseCallbuildCallFromStatement(oracle.toplink.essentials.internal.expressions.SQLStatement statement, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Return a call built from a statement. Subclasses may throw an exception if the statement is not appropriate.

        return statement.buildCall(session);
    
public java.util.VectorbuildDirectValuesFromFieldValue(java.lang.Object fieldValue)
INTERNAL: Extract the direct values from the specified field value. Return them in a vector.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public oracle.toplink.essentials.internal.helper.DatabaseFieldbuildField(java.lang.String fieldName)
INTERNAL: A DatabaseField is built from the given field name.

        DatabaseField field = new DatabaseField(fieldName);
        DatabaseTable table;

        if (field.hasTableName()) {
            table = getTable(field.getTableName());
        } else if (getDefaultTable() != null) {
            table = getDefaultTable();
        } else {
            table = getTable(getTableName());
        }

        field.setTable(table);
        return field;
    
public voidbuildField(oracle.toplink.essentials.internal.helper.DatabaseField field)
INTERNAL: The table of the field is ensured to be unique from the descriptor's tables. If the field has no table the default table is assigned. This is used only in initialization.

        DatabaseTable table;
        if (field.hasTableName()) {
            table = getTable(field.getTableName());
        } else {
            table = getDefaultTable();
        }

        field.setTable(table);
    
public java.lang.ObjectbuildFieldValueFromDirectValues(java.util.Vector directValues, java.lang.String elementDataTypeName, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Build the appropriate field value for the specified set of direct values.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public java.lang.ObjectbuildFieldValueFromForeignKeys(java.util.Vector foreignKeys, java.lang.String referenceDataTypeName, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Build and return the appropriate field value for the specified set of foreign keys (i.e. each row has the fields that make up a foreign key).

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public java.lang.ObjectbuildFieldValueFromNestedRow(oracle.toplink.essentials.internal.sessions.AbstractRecord nestedRow, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Build and return the field value from the specified nested database row.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public java.lang.ObjectbuildFieldValueFromNestedRows(java.util.Vector nestedRows, java.lang.String structureName, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Build and return the appropriate field value for the specified set of nested rows.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public oracle.toplink.essentials.internal.sessions.AbstractRecordbuildNestedRowFromFieldValue(java.lang.Object fieldValue)
INTERNAL: Build and return the nested database row from the specified field value.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
public java.util.VectorbuildNestedRowsFromFieldValue(java.lang.Object fieldValue, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Build and return the nested rows from the specified field value.

        throw DescriptorException.normalDescriptorsDoNotSupportNonRelationalExtensions(this);
    
protected voidcheckDatabase(oracle.toplink.essentials.internal.sessions.AbstractSession session)
To check that tables and fields are present in database

        if (session.getIntegrityChecker().shouldCheckDatabase()) {
            for (Enumeration enumTable = getTables().elements(); enumTable.hasMoreElements();) {
                DatabaseTable table = (DatabaseTable)enumTable.nextElement();
                if (session.getIntegrityChecker().checkTable(table, session)) {
                    // To load the fields of database into a vector
                    Vector databaseFields = new Vector();
                    Vector result = session.getAccessor().getColumnInfo(null, null, table.getName(), null, session);
                    for (Enumeration resultEnum = result.elements(); resultEnum.hasMoreElements();) {
                        AbstractRecord row = (AbstractRecord)resultEnum.nextElement();
                        databaseFields.addElement(row.get("COLUMN_NAME"));
                    }

                    // To check that the fields of descriptor are present in the database.
                    for (Enumeration row = getFields().elements(); row.hasMoreElements();) {
                        DatabaseField field = (DatabaseField)row.nextElement();
                        if (field.getTable().equals(table) && (!databaseFields.contains(field.getName()))) {
                            session.getIntegrityChecker().handleError(DescriptorException.fieldIsNotPresentInDatabase(this, table.getName(), field.getName()));
                        }
                    }
                } else {
                    session.getIntegrityChecker().handleError(DescriptorException.tableIsNotPresentInDatabase(this));
                }
            }
        }
    
public voidcheckInheritanceTreeAggregateSettings(oracle.toplink.essentials.internal.sessions.AbstractSession session, oracle.toplink.essentials.mappings.AggregateMapping mapping)
INTERNAL: Verify that an aggregate descriptor's inheritance tree is full of aggregate descriptors.

        if (!this.hasInheritance()) {
            return;
        }

        if (this.isChildDescriptor()) {
            Class parentClass = this.getInheritancePolicy().getParentClass();
            if (parentClass == this.getJavaClass()) {
                throw DescriptorException.parentClassIsSelf(this);
            }

            // recurse up the inheritance tree to the root descriptor
            session.getDescriptor(parentClass).checkInheritanceTreeAggregateSettings(session, mapping);
        } else {
            // we have a root descriptor, now verify it and all its children, grandchildren, etc.
            this.checkInheritanceTreeAggregateSettingsForChildren(session, mapping);
        }
    
private voidcheckInheritanceTreeAggregateSettingsForChildren(oracle.toplink.essentials.internal.sessions.AbstractSession session, oracle.toplink.essentials.mappings.AggregateMapping mapping)
Verify that an aggregate descriptor's inheritance tree is full of aggregate descriptors, cont.

        if (!this.isAggregateDescriptor()) {
            session.getIntegrityChecker().handleError(DescriptorException.referenceDescriptorIsNotAggregate(this.getJavaClass().getName(), mapping));
        }
        for (Enumeration stream = this.getInheritancePolicy().getChildDescriptors().elements();
                 stream.hasMoreElements();) {
            ClassDescriptor childDescriptor = (ClassDescriptor)stream.nextElement();

            // recurse down the inheritance tree to its leaves
            childDescriptor.checkInheritanceTreeAggregateSettingsForChildren(session, mapping);
        }
    
protected voidcheckMultipleTableForeignKeys(boolean userSpecifiedOrder)
INTERNAL:

        // Loop through n times to be sure that the insert order is correct. 
        // Loop n times eliminates our dependence on the order of the foreighKey 
        // relationships specified. We could do this adjustment in one pass but 
        // we would have to put the foreignKeyTables in the same order as the 
        // tables being sorted.
        Map foreignKeyTableRelationships = getMultipleTableForeignKeys();
        
        for (int i = 0; i < foreignKeyTableRelationships.size(); i++) {
            for (Iterator sourceTables = foreignKeyTableRelationships.entrySet().iterator(); sourceTables.hasNext();) {
                Map.Entry entry = (Map.Entry)sourceTables.next();
                DatabaseTable sourceTable = (DatabaseTable) entry.getKey();
                DatabaseTable targetTable = (DatabaseTable) entry.getValue();
                
                // Verify the source table is a valid.
                if (getMultipleTableInsertOrder().indexOf(sourceTable) == -1) {
                    throw DescriptorException.illegalTableNameInMultipleTableForeignKeyField(this, sourceTable);
                }                       
                
                // Verify the target table is a valid.
                if (getMultipleTableInsertOrder().indexOf(targetTable) == -1) {
                    throw DescriptorException.illegalTableNameInMultipleTableForeignKeyField(this, targetTable);
                }
                
                int sourceTableIndex = getTables().indexOf(sourceTable);
                int targetTableIndex = getTables().indexOf(targetTable);
                
                // The sourceTable must be before the targetTable to avoid 
                // foreign key constraint violations when inserting into the 
                // database.
                if (targetTableIndex < sourceTableIndex) {
                    if (userSpecifiedOrder) {
                        toggleAdditionalTablePrimaryKeyFields(targetTable, sourceTable);    
                    } else {
                        int sti = getMultipleTableInsertOrder().indexOf(sourceTable);
                        int tti = getMultipleTableInsertOrder().indexOf(targetTable);
                        
                        if (tti < sti) {
                            toggleAdditionalTablePrimaryKeyFields(targetTable, sourceTable);
                            getMultipleTableInsertOrder().removeElementAt(tti);
                            getMultipleTableInsertOrder().insertElementAt(targetTable, sti);
                        }
                    }
                }
            }
        }
    
public java.lang.Objectclone()
INTERNAL: Clones the descriptor

        ClassDescriptor clonedDescriptor = null;

        // clones itself
        try {
            clonedDescriptor = (ClassDescriptor)super.clone();
        } catch (Exception exception) {
            ;
        }

        Vector mappingsVector = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();

        // All the mappings
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping;

            mapping = (DatabaseMapping)((DatabaseMapping)mappingsEnum.nextElement()).clone();
            mapping.setDescriptor(clonedDescriptor);
            mappingsVector.addElement(mapping);
        }
        clonedDescriptor.setMappings(mappingsVector);

        Map queryKeyVector = new HashMap(getQueryKeys().size() + 2);

        // All the query keys
        for (Iterator queryKeysEnum = getQueryKeys().values().iterator();queryKeysEnum.hasNext();){
            QueryKey queryKey = (QueryKey)((QueryKey)queryKeysEnum.next()).clone();
            queryKey.setDescriptor(clonedDescriptor);
            queryKeyVector.put(queryKey.getName(), queryKey);
        }
        clonedDescriptor.setQueryKeys(queryKeyVector);

        // PrimaryKeyFields
        List primaryKeyVector = new ArrayList(getPrimaryKeyFields().size());
        List primaryKeyFields = getPrimaryKeyFields();
        for (int index = 0; index < primaryKeyFields.size(); index++) {
            DatabaseField primaryKey = (DatabaseField)((DatabaseField)primaryKeyFields.get(index)).clone();
            primaryKeyVector.add(primaryKey);
        }
        clonedDescriptor.setPrimaryKeyFields(primaryKeyVector);

        // fields.
        clonedDescriptor.setFields(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance());

        // The inheritance policy
        if (clonedDescriptor.hasInheritance()) {
            clonedDescriptor.setInheritancePolicy((InheritancePolicy)getInheritancePolicy().clone());
            clonedDescriptor.getInheritancePolicy().setDescriptor(clonedDescriptor);
        }

        // The Object builder	
        clonedDescriptor.setObjectBuilder((ObjectBuilder)getObjectBuilder().clone());
        clonedDescriptor.getObjectBuilder().setDescriptor(clonedDescriptor);

        clonedDescriptor.setEventManager((DescriptorEventManager)getEventManager().clone());
        clonedDescriptor.getEventManager().setDescriptor(clonedDescriptor);

        // The Query manager
        clonedDescriptor.setQueryManager((DescriptorQueryManager)getQueryManager().clone());
        clonedDescriptor.getQueryManager().setDescriptor(clonedDescriptor);

        //fetch group
        if (hasFetchGroupManager()) {
            clonedDescriptor.setFetchGroupManager((FetchGroupManager)getFetchGroupManager().clone());
        }

        clonedDescriptor.setIsIsolated(this.isIsolated());

        // Bug 3037701 - clone several more elements
        clonedDescriptor.setInstantiationPolicy((InstantiationPolicy)this.instantiationPolicy.clone());
        clonedDescriptor.setCopyPolicy((CopyPolicy)this.copyPolicy.clone());
        if (getOptimisticLockingPolicy() != null) {
            clonedDescriptor.setOptimisticLockingPolicy((OptimisticLockingPolicy)this.getOptimisticLockingPolicy().clone());
        }

        return (Object)clonedDescriptor;
    
public voidconvertClassNamesToClasses(java.lang.ClassLoader classLoader)
INTERNAL: Convert all the class-name-based settings in this Descriptor to actual class-based settings. This method is used when converting a project that has been built with class names to a project with classes.

param
classLoader

        Class descriptorClass = null;
        Class amendmentClass = null;
        try{
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    descriptorClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(getJavaClassName(), true, classLoader));
                } catch (PrivilegedActionException exception) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(getAmendmentClassName(), exception.getException());
                }
            } else {
                descriptorClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(getJavaClassName(), true, classLoader);
            }
            if (getAmendmentClassName() != null){
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        amendmentClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(getAmendmentClassName(), true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(getAmendmentClassName(), exception.getException());
                   }
                } else {
                    amendmentClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(getAmendmentClassName(), true, classLoader);
                }            
            }
        } catch (ClassNotFoundException exc){
            throw ValidationException.classNotFoundWhileConvertingClassNames(getAmendmentClassName(), exc);
        }
        setJavaClass(descriptorClass);
        if (amendmentClass != null){
            setAmendmentClass(amendmentClass);
        }
        Iterator mappings = getMappings().iterator();
        while (mappings.hasNext()){
            ((DatabaseMapping)mappings.next()).convertClassNamesToClasses(classLoader);
        }
        if (inheritancePolicy != null){
            inheritancePolicy.convertClassNamesToClasses(classLoader);
        }
        if (instantiationPolicy != null){
            instantiationPolicy.convertClassNamesToClasses(classLoader);
        }
        if (hasCMPPolicy()) {
            getCMPPolicy().convertClassNamesToClasses(classLoader);
        }
        queryManager.convertClassNamesToClasses(classLoader);
    
public voidcreateCopyPolicy(java.lang.String policyType)
PUBLIC: Create a copy policy of the type passed in as a string.

        if (policyType.equals("clone")) {
            useCloneCopyPolicy();
            return;
        }
        if (policyType.equals("constructor")) {
            useInstantiationCopyPolicy();
            return;
        }
    
public voidcreateInstantiationPolicy(java.lang.String policyType)
PUBLIC: Create a instantiation policy of the type passed in as a string.

        if (policyType.equals("static method")) {
            //do nothing for now
            return;
        }
        if (policyType.equals("constructor")) {
            useDefaultConstructorInstantiationPolicy();
            return;
        }
        if (policyType.equals("factory")) {
            //do nothing for now
            return;
        }
    
public voiddescriptorIsAggregate()
PUBLIC: Sets the descriptor to be an aggregate. An aggregate descriptor is contained within another descriptor's table. Aggregate descriptors are insert/updated/deleted with their owner and cannot exist without their owner as they share the same row. Aggregates are not cached (they are cached as part of their owner) and cannot be read/written/deleted/registered. All aggregate descriptors must call this.

        setDescriptorType(AGGREGATE);
    
public voiddescriptorIsAggregateCollection()
PUBLIC: Sets the descriptor to be part of an aggregate collection. An aggregate collection descriptor stored in a seperate table but some of the fields (the primary key) comes from its owner. Aggregate collection descriptors are insert/updated/deleted with their owner and cannot exist without their owner as they share the primary key. Aggregate collections are not cached (they are cached as part of their owner) and cannot be read/written/deleted/registered. All aggregate collection descriptors must call this.

        setDescriptorType(AGGREGATE_COLLECTION);
    
public voiddescriptorIsNormal()
PUBLIC: Sets the descriptor to be normal. This is the default and means the descriptor is not aggregate or for an interface.

        setDescriptorType(NORMAL);
    
public voiddisableCacheHits()
PUBLIC: Allow for cache hits on primary key read object queries to be disabled. This can be used with {@link #alwaysRefreshCache} or {@link #alwaysRefreshCacheOnRemote} to ensure queries always go to the database.

        setShouldDisableCacheHits(true);
    
public voiddontAlwaysConformResultsInUnitOfWork()
PUBLIC: The descriptor is defined to not conform the results in unit of work in read query. Default.

        setShouldAlwaysConformResultsInUnitOfWork(false);
    
public voiddontAlwaysRefreshCache()
PUBLIC: This method is the equivalent of calling {@link #setShouldAlwaysRefreshCache} with an argument of false: it ensures that a Descriptor is not configured to always refresh the cache if data is received from the database by any query.

see
#alwaysRefreshCache

        setShouldAlwaysRefreshCache(false);
    
public voiddontDisableCacheHits()
PUBLIC: Allow for cache hits on primary key read object queries.

see
#disableCacheHits()

        setShouldDisableCacheHits(false);
    
public voiddontOnlyRefreshCacheIfNewerVersion()
PUBLIC: This method is the equivalent of calling {@link #setShouldOnlyRefreshCacheIfNewerVersion} with an argument of false: it ensures that a Descriptor is not configured to only refresh the cache if the data received from the database by a query is newer than the data in the cache (as determined by the optimistic locking field).

see
#onlyRefreshCacheIfNewerVersion

        setShouldOnlyRefreshCacheIfNewerVersion(false);
    
protected oracle.toplink.essentials.internal.helper.DatabaseTableextractDefaultTable()
INTERNAL: The first table in the tables is always treated as default.

        if (getTables().isEmpty()) {
            if (isChildDescriptor()) {
                return getInheritancePolicy().getParentDescriptor().extractDefaultTable();
            } else {
                return null;
            }
        }

        return (DatabaseTable)getTables().firstElement();
    
public java.util.MapgetAdditionalTablePrimaryKeyFields()
INTERNAL: This is used to map the primary key field names in a multiple table descriptor.

        if (additionalTablePrimaryKeyFields == null) {
            additionalTablePrimaryKeyFields = new HashMap(5);
        }
        return additionalTablePrimaryKeyFields;
    
public java.lang.StringgetAlias()
PUBLIC: Get the alias


        /* CR3310: Steven Vo
         *   Default alias to the Java class name if the alias is not set
         */
        if ((alias == null) && (getJavaClassName() != null)) {
            alias = oracle.toplink.essentials.internal.helper.Helper.getShortClassName(getJavaClassName());
        }
        return alias;
    
public java.util.VectorgetAllFields()
INTERNAL: Return all the fields which include all child class fields. By default it is initialized to the fields for the current descriptor.

        return allFields;
    
public java.lang.ClassgetAmendmentClass()
PUBLIC: Return the amendment class. The amendment method will be called on the class before initialization to allow for it to initialize the descriptor. The method must be a public static method on the class.

        return amendmentClass;
    
public java.lang.StringgetAmendmentClassName()
INTERNAL: Return amendment class name, used by the MW.

        if ((amendmentClassName == null) && (amendmentClass != null)) {
            amendmentClassName = amendmentClass.getName();
        }
        return amendmentClassName;
    
public java.lang.StringgetAmendmentMethodName()
PUBLIC: Return the amendment method. This will be called on the amendment class before initialization to allow for it to initialize the descriptor. The method must be a public static method on the class.

        return amendmentMethodName;
    
public oracle.toplink.essentials.descriptors.CMPPolicygetCMPPolicy()
ADVANCED: Return the cmp descriptor that holds EJB CMP specific information. This will be null unless explicitly set, or after CMP deoloyment. This can only be specified when using CMP for bean class descriptors. This must be set explicitly if any setting need to be configured and before calling getCMPPolicy().

        return cmpPolicy;
    
public oracle.toplink.essentials.descriptors.invalidation.CacheInvalidationPolicygetCacheInvalidationPolicy()
PUBLIC: Return the CacheInvalidationPolicy for this descriptor For uninitialized cache invalidation policies, this will return a NoExpiryCacheInvalidationPolicy

return
CacheInvalidationPolicy
see
oracle.toplink.essentials.descriptors.invalidation.CacheInvalidationPolicy

        if (cacheInvalidationPolicy == null) {
            cacheInvalidationPolicy = new NoExpiryCacheInvalidationPolicy();
        }
        return cacheInvalidationPolicy;
    
public java.util.VectorgetCascadeLockingPolicies()
INTERNAL:

        return cascadeLockingPolicies;
     
public java.util.VectorgetConstraintDependencies()
ADVANCED: TopLink automatically orders database access through the foreign key information provided in 1:1 and 1:m mappings. In some case when 1:1 are not defined it may be required to tell the descriptor about a constraint, this defines that this descriptor has a foreign key constraint to another class and must be inserted after instances of the other class.

        return constraintDependencies;
    
public oracle.toplink.essentials.descriptors.copying.CopyPolicygetCopyPolicy()
INTERNAL: Returns the copy policy.

        return copyPolicy;
    
public oracle.toplink.essentials.queryframework.FetchGroupgetDefaultFetchGroup()
INTERNAL: Return the default fetch group on the descriptor. All read object and read all queries will use the default fetch group if no fetch group is explicitly defined for the query.

        if (!hasFetchGroupManager()) {
            //fetch group manager is not set, therefore no default fetch group.
            return null;
        }
        return getFetchGroupManager().getDefaultFetchGroup();
    
public oracle.toplink.essentials.internal.helper.DatabaseTablegetDefaultTable()
INTERNAL: The first table in the tables is always treated as default.

        return defaultTable;
    
public oracle.toplink.essentials.descriptors.DescriptorEventManagergetDescriptorEventManager()
PUBLIC: Get the event manager for the descriptor. The event manager is responsible for managing the pre/post selectors.

        return getEventManager();
    
public oracle.toplink.essentials.descriptors.InheritancePolicygetDescriptorInheritancePolicy()
PUBLIC: The inheritance policy is used to define how a descriptor takes part in inheritance. All inheritance properties for both child and parent classes is configured in inheritance policy. Caution must be used in using this method as it lazy initializes an inheritance policy. Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.

        return getInheritancePolicy();
    
public oracle.toplink.essentials.descriptors.DescriptorQueryManagergetDescriptorQueryManager()
PUBLIC: Return the queryManager. The query manager can be used to specify customization of the SQL that TopLink generates for this descriptor.

        return queryManager;
    
public intgetDescriptorType()
ADVANCED: return the descriptor type (NORMAL by default, others include INTERFACE, AGGREGATE, AGGREGATE COLLECTION)

        return descriptorType;
    
public java.lang.StringgetDescriptorTypeValue()
INTERNAL: This method is explicitly used by the XML reader.

        if (isAggregateCollectionDescriptor()) {
            return "Aggregate collection";
        } else if (isAggregateDescriptor()) {
            return "Aggregate";
        } else {
            // Default.
            return "Normal";
        }
    
public oracle.toplink.essentials.descriptors.DescriptorEventManagergetEventManager()
PUBLIC: Get the event manager for the descriptor. The event manager is responsible for managing the pre/post selectors.

        return eventManager;
    
public oracle.toplink.essentials.descriptors.FetchGroupManagergetFetchGroupManager()
PUBLIC: Get the fetch group manager for the descriptor. The fetch group manager is responsible for managing the fetch group behaviors and operations. To use the fetch group, the domain object must implement FetchGroupTracker interface. Otherwise, a descriptor validation exception would throw during initialization. NOTE: This is currently only supported in CMP2.

see
oracle.toplink.essentials.queryframework.FetchGroupTracker

        return fetchGroupManager;
    
public java.util.VectorgetFields()
INTERNAL: Return all the fields

        return fields;
    
public java.lang.ClassgetIdentityMapClass()
INTERNAL: Return the class of identity map to be used by this descriptor. The default is the "SoftCacheWeakIdentityMap".

        return identityMapClass;
    
public intgetIdentityMapSize()
PUBLIC: Return the size of the identity map.

        return identityMapSize;
    
public oracle.toplink.essentials.descriptors.InheritancePolicygetInheritancePolicy()
PUBLIC: The inheritance policy is used to define how a descriptor takes part in inheritance. All inheritance properties for both child and parent classes is configured in inheritance policy. Caution must be used in using this method as it lazy initializes an inheritance policy. Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.

        if (inheritancePolicy == null) {
            // Lazy initialize to conserve space in non-inherited classes.
            setInheritancePolicy(new oracle.toplink.essentials.descriptors.InheritancePolicy(this));
        }
        return inheritancePolicy;
    
public oracle.toplink.essentials.descriptors.InheritancePolicygetInheritancePolicyOrNull()
INTERNAL: Return the inheritance policy.

        return inheritancePolicy;
    
public oracle.toplink.essentials.internal.descriptors.InstantiationPolicygetInstantiationPolicy()
INTERNAL: Returns the instantiation policy.

        return instantiationPolicy;
    
public java.lang.ClassgetJavaClass()
PUBLIC: Return the java class.

        return javaClass;
    
public java.lang.StringgetJavaClassName()
Return the class name, used by the MW.

        if ((javaClassName == null) && (javaClass != null)) {
            javaClassName = javaClass.getName();
        }
        return javaClassName;
    
public java.util.ListgetLockableMappings()
INTERNAL: Returns a reference to the mappings that must be traverse when locking

        if (this.lockableMappings == null) {
            this.lockableMappings = new ArrayList();
        }
        return this.lockableMappings;
    
public oracle.toplink.essentials.mappings.DatabaseMappinggetMappingForAttributeName(java.lang.String attributeName)
PUBLIC: Returns the mapping associated with a given attribute name. This can be used to find a descriptors mapping in a amendment method before the descriptor has been initialized.

        // ** Don't use this internally, just for amendments, see getMappingForAttributeName on ObjectBuilder.
        for (Enumeration mappingsNum = mappings.elements(); mappingsNum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsNum.nextElement();
            if ((mapping.getAttributeName() != null) && mapping.getAttributeName().equals(attributeName)) {
                return mapping;
            }
        }
        return null;
    
public java.util.VectorgetMappings()
PUBLIC: Returns mappings

        return mappings;
    
public java.util.VectorgetMultipleTableForeignKeyAssociations()
INTERNAL: Returns the foreign key relationships used for multiple tables which were specified by the user. Used by the Project XML writer to output these associations

see
#adjustMultipleTableInsertOrder()
return
java.util.Hashtable

        Vector associations = new Vector(getAdditionalTablePrimaryKeyFields().size() * 2);
        Iterator tablesHashtable = getAdditionalTablePrimaryKeyFields().values().iterator();
        while (tablesHashtable.hasNext()) {
            Map tableHash = (Map)tablesHashtable.next();
            Iterator fieldEnumeration = tableHash.keySet().iterator();
            while (fieldEnumeration.hasNext()) {
                DatabaseField keyField = (DatabaseField)fieldEnumeration.next();

                //PRS#36802(CR#2057) contains() is changed to containsKey()
                if (getMultipleTableForeignKeys().containsKey(keyField.getTable())) {
                    Association association = new Association(keyField.getQualifiedName(), ((DatabaseField)tableHash.get(keyField)).getQualifiedName());
                    associations.addElement(association);
                }
            }
        }
        return associations;
    
public java.util.MapgetMultipleTableForeignKeys()
INTERNAL: Returns the foreign key relationships used for multiple tables which were specified by the user. The key of the Map is the field in the source table of the foreign key relationship. The value is the field name of the target table.

see
#adjustMultipleTableInsertOrder()

        return multipleTableForeignKeys;
    
public java.util.VectorgetMultipleTableInsertOrder()
INTERNAL: Returns the Vector of DatabaseTables in the order which INSERTS should take place. This order is determined by the foreign key fields which are specified by the user.

return
java.util.Vector

        return multipleTableInsertOrder;
    
public java.util.VectorgetMultipleTablePrimaryKeyAssociations()
INTERNAL: Returns the foreign key relationships used for multiple tables which were specified by the user. Used by the Project XML writer to output these associations

see
#adjustMultipleTableInsertOrder()

        Vector associations = new Vector(getAdditionalTablePrimaryKeyFields().size() * 2);
        Iterator tablesHashtable = getAdditionalTablePrimaryKeyFields().values().iterator();
        while (tablesHashtable.hasNext()) {
            Map tableHash = (Map)tablesHashtable.next();
            Iterator fieldEnumeration = tableHash.keySet().iterator();
            while (fieldEnumeration.hasNext()) {
                DatabaseField keyField = (DatabaseField)fieldEnumeration.next();

                //PRS#36802(CR#2057) contains() is changed to containsKey()
                if (!getMultipleTableForeignKeys().containsKey(keyField.getTable())) {
                    Association association = new Association(keyField.getQualifiedName(), ((DatabaseField)tableHash.get(keyField)).getQualifiedName());
                    associations.addElement(association);
                }
            }
        }
        return associations;
    
public oracle.toplink.essentials.internal.descriptors.ObjectBuildergetObjectBuilder()
INTERNAL: Return the object builder

        return objectBuilder;
    
public oracle.toplink.essentials.descriptors.changetracking.ObjectChangePolicygetObjectChangePolicy()
PUBLIC: Return this objects ObjectChangePolicy.

        // part of fix for 4410581: project xml must save change policy
        // if no change-policy XML element, field is null: lazy-init to default
        if (changePolicy == null) {
            changePolicy = new DeferredChangeDetectionPolicy();
        }
        return changePolicy;
    
public oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicygetOptimisticLockingPolicy()
PUBLIC: Returns the OptimisticLockingPolicy. By default this is an instance of VersionLockingPolicy.

        return optimisticLockingPolicy;
    
public java.util.VectorgetPrimaryKeyFieldNames()
PUBLIC: Return the names of all the primary keys.

        Vector<String> result = new Vector(getPrimaryKeyFields().size());
        List primaryKeyFields = getPrimaryKeyFields();
        for (int index = 0; index < primaryKeyFields.size(); index++) {
            result.addElement(((DatabaseField)primaryKeyFields.get(index)).getQualifiedName());
        }

        return result;
    
public java.util.ListgetPrimaryKeyFields()
INTERNAL: Return all the primary key fields

        return primaryKeyFields;
    
public java.util.MapgetProperties()
PUBLIC: Returns the user defined properties.

        if (properties == null) {
            properties = new HashMap(5);
        }
        return properties;
    
public java.lang.ObjectgetProperty(java.lang.String name)
PUBLIC: Returns the descriptor property associated the given String.

        return getProperties().get(name);
    
public oracle.toplink.essentials.querykeys.QueryKeygetQueryKeyNamed(java.lang.String queryKeyName)
INTERNAL: Return the query key with the specified name

        return this.getQueryKeys().get(queryKeyName);
    
public java.util.MapgetQueryKeys()
PUBLIC: Return the query keys.

        return queryKeys;
    
public oracle.toplink.essentials.descriptors.DescriptorQueryManagergetQueryManager()
PUBLIC: Return the queryManager. The query manager can be used to specify customization of the SQL that TopLink generates for this descriptor.

        return queryManager;
    
public oracle.toplink.essentials.internal.helper.DatabaseFieldgetSequenceNumberField()
INTERNAL: Get sequence number field

        return sequenceNumberField;
    
public java.lang.StringgetSequenceNumberFieldName()
PUBLIC: Get sequence number field name

        if (getSequenceNumberField() == null) {
            return null;
        }
        return getSequenceNumberField().getQualifiedName();
    
public java.lang.StringgetSequenceNumberName()
PUBLIC: Get sequence number name

        return sequenceNumberName;
    
public java.lang.StringgetSessionName()
INTERNAL: Return the name of the session local to this descriptor. This is used by the session broker.

        return sessionName;
    
public oracle.toplink.essentials.internal.helper.DatabaseTablegetTable(java.lang.String tableName)
INTERNAL: Checks if table name exists with the current descriptor or not.

        if (getTables().isEmpty()) {
            return null;// Assume aggregate descriptor.
        }

        for (Enumeration tables = getTables().elements(); tables.hasMoreElements();) {
            DatabaseTable table = (DatabaseTable)tables.nextElement();

            if (table.getName().equals(tableName)) {
                return table;
            }
        }

        if (isAggregateDescriptor()) {
            return getDefaultTable();
        }
        throw DescriptorException.tableNotPresent(tableName, this);
    
public java.lang.StringgetTableName()
PUBLIC: Return the name of the descriptor's first table. This method must only be called on single table descriptors.

        if (getTables().isEmpty()) {
            return null;
        } else {
            return ((DatabaseTable)getTables().firstElement()).getName();
        }
    
public java.util.VectorgetTableNames()
PUBLIC: Return the table names.

        Vector tableNames = new Vector(getTables().size());
        for (Enumeration fieldsEnum = getTables().elements(); fieldsEnum.hasMoreElements();) {
            tableNames.addElement(((DatabaseTable)fieldsEnum.nextElement()).getQualifiedName());
        }

        return tableNames;
    
public java.util.VectorgetTables()
INTERNAL: Return all the tables.

        return tables;
    
public oracle.toplink.essentials.internal.helper.DatabaseFieldgetTypedField(oracle.toplink.essentials.internal.helper.DatabaseField field)
INTERNAL: searches first descriptor than its ReturningPolicy for an equal field

        boolean mayBeMoreThanOne = hasMultipleTables() && !field.hasTableName();
        DatabaseField foundField = null;
        for (int j = 0; j < getFields().size(); j++) {
            DatabaseField descField = (DatabaseField)getFields().elementAt(j);
            if (field.equals(descField)) {
                if (descField.getType() != null) {
                    foundField = descField;
                    if (!mayBeMoreThanOne || descField.getTable().equals(getDefaultTable())) {
                        break;
                    }
                }
            }
        }
        if (foundField != null) {
            foundField = (DatabaseField)foundField.clone();
            if (!field.hasTableName()) {
                foundField.setTableName("");
            }
        }

        return foundField;
    
public oracle.toplink.essentials.descriptors.WrapperPolicygetWrapperPolicy()
ADVANCED: Return the WrapperPolicy for this descriptor. This advacned feature can be used to wrap objects with other classes such as CORBA TIE objects or EJBs.

        return wrapperPolicy;
    
public booleanhasCMPPolicy()
INTERNAL: Return if the descriptor has a CMP policy.

        return (cmpPolicy != null);
    
public booleanhasCascadeLockingPolicies()
INTERNAL:

        return !cascadeLockingPolicies.isEmpty();
     
public booleanhasDependencyOnParts()
INTERNAL: Checks if the class has any private owned parts or other dependencies, (i.e. M:M join table).

        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappings.nextElement();
            if (mapping.hasDependency()) {
                return true;
            }
        }

        return false;
    
public booleanhasFetchGroupManager()
INTERNAL: Return if the descriptor has a fecth group manager asociated with.

        return (fetchGroupManager != null);
    
public booleanhasInheritance()
INTERNAL: Return if this descriptor is involved in inheritence, (is child or parent).

        return (inheritancePolicy != null);
    
public booleanhasMultipleTables()
INTERNAL: Check if descriptor has multiple tables

        return (getTables().size() > 1);
    
public booleanhasPrivatelyOwnedParts()
INTERNAL: Checks if the class has any private owned parts are not

        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappings.nextElement();
            if (mapping.isPrivateOwned()) {
                return true;
            }
        }

        return false;
    
public booleanhasQueryKeyOrMapping(java.lang.String attributeName)
INTERNAL: Checks to see if it has a query key or mapping with the specified name or not.

        return (getQueryKeys().containsKey(attributeName) || (getObjectBuilder().getMappingForAttributeName(attributeName) != null));
    
public booleanhasSimplePrimaryKey()
INTERNAL: PERF: Return if the primary key is simple (direct-mapped) to allow fast extraction.

        return hasSimplePrimaryKey;
    
public booleanhasWrapperPolicy()
INTERNAL: Return if a wrapper policy is used.

        return getWrapperPolicy() != null;
    
public voidinitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialize the mappings as a seperate step. This is done as a seperate step to ensure that inheritence has been first resolved.

    
        // These cached settings on the project must be set even if descriptor is initialized.
        // If defined as read-only, add to it's project's default read-only classes collection.
        if (shouldBeReadOnly() && (!session.getDefaultReadOnlyClasses().contains(getJavaClass()))) {
            session.getDefaultReadOnlyClasses().add(getJavaClass());
        }
        // Record that there is an isolated class in the project.
        if (isIsolated()) {
            session.getProject().setHasIsolatedClasses(true);
        }
        // Record that there is a non-CMP1/2 object in the project.
        if ((! hasCMPPolicy()) || getCMPPolicy().isCMP3Policy()) {
            session.getProject().setIsPureCMP2Project(false);
        }
        
        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(INITIALIZED) || isInvalid()) {
            return;
        }

        setInitializationStage(INITIALIZED);

        // make sure that parent mappings are initialized?
        if (isChildDescriptor()) {
            getInheritancePolicy().getParentDescriptor().initialize(session);
            if (getInheritancePolicy().getParentDescriptor().isIsolated()) {
                //if the parent is isolated then the child must be isolated as well.
                this.setIsIsolated(true);
            }
        }

        // Mappings must be sorted before field are collected in the order of the mapping for indexes to work.
        // Sorting the mappings to ensure that all DirectToFields get merged before all other mappings
        // This prevents null key errors when merging maps
        if (shouldOrderMappings()) {
            Vector mappings = getMappings();
            Object[] mappingsArray = new Object[mappings.size()];
            for (int index = 0; index < mappings.size(); index++) {
                mappingsArray[index] = mappings.elementAt(index);
            }
            TOPSort.quicksort(mappingsArray, new MappingCompare());
            mappings = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(mappingsArray.length);
            for (int index = 0; index < mappingsArray.length; index++) {
                mappings.addElement(mappingsArray[index]);
            }
            setMappings(mappings);     
        }
        
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            validateMappingType(mapping);
            mapping.initialize(session);
            if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
                getLockableMappings().add(mapping);
            }
            
            // Add all the fields in the mapping to myself.
            Helper.addAllUniqueToVector(getFields(), mapping.getFields());
        }
        
        // PERF: Dont initialize locking until after fields have been computed so
        // field is in correct position.
        if (!isAggregateDescriptor()) {
            if (!isChildDescriptor()) {
                // Add write lock field to getFields
                if (usesOptimisticLocking()) {
                    getOptimisticLockingPolicy().initializeProperties();
                }
            }
        }

        // All the query keys should be initialized.
        for (Iterator queryKeys = getQueryKeys().values().iterator(); queryKeys.hasNext();) {
            QueryKey queryKey = (QueryKey)queryKeys.next();
            queryKey.initialize(this);
        }

        // If this has inheritence then it needs to be initialized before all fields is set.
        if (hasInheritance()) {
            getInheritancePolicy().initialize(session);
            if (getInheritancePolicy().isChildDescriptor()) {
                for (Iterator iterator = getInheritancePolicy().getParentDescriptor().getMappings().iterator();
                         iterator.hasNext();) {
                    DatabaseMapping mapping = (DatabaseMapping)iterator.next();
                    if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
                        getLockableMappings().add(mapping);// add those mappings from the parent.
                    }
                }
            }
        }

        // cr 4097  Ensure that the mappings are ordered after the superclasses mappings have been added.
        // This ensures that the mappings in the child class are ordered correctly
        // I am sorting the mappings to ensure that all DirectToFields get merged before all other mappings
        // This prevents null key errors when merging maps
        // This resort will change the previous sort order, only do it if has inheritance.
        if (this.hasInheritance() && shouldOrderMappings()) {
            Vector mappings = getMappings();
            Object[] mappingsArray = new Object[mappings.size()];
            for (int index = 0; index < mappings.size(); index++) {
                mappingsArray[index] = mappings.elementAt(index);
            }
            TOPSort.quicksort(mappingsArray, new MappingCompare());
            mappings = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(mappingsArray.length);
            for (int index = 0; index < mappingsArray.length; index++) {
                mappings.addElement(mappingsArray[index]);
            }
            setMappings(mappings);
        }

        // Initialize the allFields to its fields, this can be done now because the fields have been computed.
        setAllFields((Vector)getFields().clone());

        getObjectBuilder().initialize(session);
        
        if (shouldOrderMappings()) {
            // PERF: Ensure direct primary key mappings are first.
            for (int index = getObjectBuilder().getPrimaryKeyMappings().size() - 1; index >= 0; index--) {
                DatabaseMapping mapping = (DatabaseMapping) getObjectBuilder().getPrimaryKeyMappings().get(index);
                if ((mapping != null) && mapping.isDirectToFieldMapping()) {
                    getMappings().remove(mapping);
                    getMappings().add(0, mapping);
                    DatabaseField field = ((AbstractDirectMapping) mapping).getField();
                    getFields().remove(field);
                    getFields().add(0, field);
                    getAllFields().remove(field);
                    getAllFields().add(0, field);
                }
            }
        }

        if (usesOptimisticLocking() && (!isChildDescriptor())) {
            getOptimisticLockingPolicy().initialize(session);
        }
        if (hasWrapperPolicy()) {
            getWrapperPolicy().initialize(session);
        }
        getQueryManager().initialize(session);
        getEventManager().initialize(session);
        getCopyPolicy().initialize(session);
        getInstantiationPolicy().initialize(session);

        if (this.getCMPPolicy() != null) {
            this.getCMPPolicy().initialize(this, session);
        }

        //validate the fetch group setting during descriptor initialization
        if (hasFetchGroupManager() && !(Helper.classImplementsInterface(javaClass, ClassConstants.FetchGroupTracker_class))) {
            //to use fetch group, the domain class must implement FetchGroupTracker interface
            session.getIntegrityChecker().handleError(DescriptorException.needToImplementFetchGroupTracker(javaClass, this));
        }        
    
public voidinitializeAggregateInheritancePolicy(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This initialized method is used exclusively for inheritance. It passes in true if the child descriptor is isolated. This is needed by regular aggregate descriptors (because they are screwed up); but not by SDK aggregate descriptors.

        ClassDescriptor parentDescriptor = session.getDescriptor(getInheritancePolicy().getParentClass());
        parentDescriptor.getInheritancePolicy().addChildDescriptor(this);
    
public voidinitializeMultipleTablePrimaryKeyFields()
INTERNAL: Rebuild the multiple table primary key map.

        int additionalTablesSize = getTables().size() - 1;
        boolean isChild = hasInheritance() && getInheritancePolicy().isChildDescriptor();
        if (isChild) {
            additionalTablesSize = getTables().size() - getInheritancePolicy().getParentDescriptor().getTables().size();
        }
        if (additionalTablesSize < 1) {
            return;
        }
        ExpressionBuilder builder = new ExpressionBuilder();
        Expression joinExpression = getQueryManager().getMultipleTableJoinExpression();
        for (int index = getTables().size() - additionalTablesSize; index < getTables().size();
                 index++) {
            DatabaseTable table = (DatabaseTable)getTables().elementAt(index);
            Map oldKeyMapping = (Map)getAdditionalTablePrimaryKeyFields().get(table);
            if (oldKeyMapping != null) {
                if (!getQueryManager().hasCustomMultipleTableJoinExpression()) {
                    // Build the multiple table join expression resulting from the fk relationships.
                    for (Iterator enumtr = oldKeyMapping.keySet().iterator(); enumtr.hasNext();) {
                        DatabaseField sourceTableField = (DatabaseField)enumtr.next();
                        DatabaseField targetTableField = (DatabaseField)oldKeyMapping.get(sourceTableField);
                        DatabaseTable sourceTable = sourceTableField.getTable();
                        DatabaseTable targetTable = targetTableField.getTable();

                        // Must add this field to read, so translations work on database row, this could be either.
                        if (!getFields().contains(sourceTableField)) {
                            getFields().addElement(sourceTableField);
                        }
                        if (!getFields().contains(targetTableField)) {
                            getFields().addElement(targetTableField);
                        }

                        Expression keyJoinExpression = builder.getField(targetTableField).equal(builder.getField(sourceTableField));
                        joinExpression = keyJoinExpression.and(joinExpression);
                        
                        getQueryManager().getTablesJoinExpressions().put(targetTable, keyJoinExpression);
                        if(isChild) {
                            getInheritancePolicy().addChildTableJoinExpressionToAllParents(targetTable, keyJoinExpression);
                        }
                    }
                }
            } else {
                // If the user has specified a custom multiple table join then we do not assume that the secondary tables have identically named pk as the primary table.
                // No additional fk info was specified so assume the pk field(s) are the named the same in the additional table.
                Map newKeyMapping = new HashMap(getPrimaryKeyFields().size() + 1);
                getAdditionalTablePrimaryKeyFields().put(table, newKeyMapping);

                // For each primary key field in the primary table, add a pk relationship from the primary table's pk field to the assumed identically named secondary pk field.
                List primaryKeyFields = getPrimaryKeyFields();
                for (int pkIndex = 0; pkIndex < primaryKeyFields.size(); pkIndex++) {
                    DatabaseField primaryKeyField = (DatabaseField)primaryKeyFields.get(pkIndex);
                    DatabaseField secondaryKeyField = (DatabaseField)primaryKeyField.clone();
                    secondaryKeyField.setTable(table);
                    newKeyMapping.put(primaryKeyField, secondaryKeyField);
                    // Must add this field to read, so translations work on database row.
                    getFields().addElement(secondaryKeyField);

                    if (!getQueryManager().hasCustomMultipleTableJoinExpression()) {
                        Expression keyJoinExpression = builder.getField(secondaryKeyField).equal(builder.getField(primaryKeyField));
                        joinExpression = keyJoinExpression.and(joinExpression);

                        getQueryManager().getTablesJoinExpressions().put(table, keyJoinExpression);
                        if(isChild) {
                            getInheritancePolicy().addChildTableJoinExpressionToAllParents(table, keyJoinExpression);
                        }
                    }
                }
            }
        }
        if (joinExpression != null) {
            getQueryManager().setInternalMultipleTableJoinExpression(joinExpression);
        }
        if (getQueryManager().hasCustomMultipleTableJoinExpression()) {
            Map tablesJoinExpressions = SQLSelectStatement.mapTableToExpression(joinExpression, getTables());
            getQueryManager().getTablesJoinExpressions().putAll(tablesJoinExpressions);
            if(isChild) {
                for (int index = getTables().size() - additionalTablesSize; index < getTables().size();
                         index++) {
                    DatabaseTable table = (DatabaseTable)getTables().elementAt(index);
                    getInheritancePolicy().addChildTableJoinExpressionToAllParents(table, (Expression)tablesJoinExpressions.get(table));
                }
            }
        }
    
protected voidinitializePrimaryKey(oracle.toplink.essentials.internal.helper.DatabaseField primaryKey)
INTERNAL:

        buildField(primaryKey);
        if (!primaryKey.getTable().equals(getDefaultTable())) {
            getPrimaryKeyFields().remove(primaryKey);
        }
    
protected voidinitializeProperties(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialize the descriptor properties such as write lock and sequecning.

        if (!isAggregateDescriptor()) {
            if (!isChildDescriptor()) {
                // Initialize the primary key fields
                List primaryKeyFields = (List)((ArrayList)getPrimaryKeyFields()).clone();
                for (int index = 0; index < primaryKeyFields.size(); index++) {
                    DatabaseField primaryKey = (DatabaseField)primaryKeyFields.get(index);
                    initializePrimaryKey(primaryKey);
                }
            }

            // build sequence number field
            if (getSequenceNumberField() != null) {
                buildField(getSequenceNumberField());
            }
        }

        // Set the local session name for the session broker.
        setSessionName(session.getName());
    
public booleanisAggregateCollectionDescriptor()
PUBLIC: Return true if this descriptor is an aggregate collection descriptor

        return (getDescriptorType() == AGGREGATE_COLLECTION);
    
public booleanisAggregateDescriptor()
PUBLIC: Return true if this descriptor is an aggregate descriptor

        return (getDescriptorType() == AGGREGATE);
    
public booleanisChildDescriptor()
PUBLIC: Return if the descriptor defines inheritence and is a child.

        return hasInheritance() && getInheritancePolicy().isChildDescriptor();
    
public booleanisDescriptorForCMP()
INTERNAL: Return true if the descriptor is a CMP entity descriptor

        return (this.getCMPPolicy() != null);
    
public booleanisFullyInitialized()
INTERNAL: Check if the descriptor is finished initialization.

        return this.initializationStage == POST_INITIALIZED;
    
protected booleanisInitialized(int initializationStage)
INTERNAL: Check if descriptor is already initialized for the level of initialization. 1 = pre 2 = mapping 3 = post

        return this.initializationStage >= initializationStage;
    
public booleanisInvalid()
INTERNAL: Return if an error occured during initialization which should abort any further initialization.

        return this.initializationStage == ERROR;
    
public booleanisIsolated()
PUBLIC: Returns true if the descriptor represents an isolated class

        return this.isIsolated;
    
public booleanisMultipleTableDescriptor()
INTERNAL: Return if this descriptor has more than one table.

        return getTables().size() > 1;
    
public booleanisPrimaryKeySetAfterInsert(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Indicates whether pk or some of its components set after insert into the database. Shouldn't be called before Descriptor has been initialized.

        return (usesSequenceNumbers() && session.getSequencing().shouldAcquireValueAfterInsert(getJavaClass()));
    
public voidonlyRefreshCacheIfNewerVersion()
PUBLIC: PUBLIC: This method is the equivalent of calling {@link #setShouldOnlyRefreshCacheIfNewerVersion} with an argument of true: it configures a Descriptor to only refresh the cache if the data received from the database by a query is newer than the data in the cache (as determined by the optimistic locking field) and as long as one of the following is true:
  • the Descriptor was configured by calling {@link #alwaysRefreshCache} or {@link #alwaysRefreshCacheOnRemote},
  • the query was configured by calling {@link oracle.toplink.essentials.queryframework.ObjectLevelReadQuery#refreshIdentityMapResult}, or
  • the query was a call to {@link oracle.toplink.essentials.sessions.Session#refreshObject}

However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink will first look in the cache for the object. If the object is in the cache, the cached object is returned and data is not refreshed. To avoid cache hits, use the {@link #disableCacheHits} method.

Also note that the {@link oracle.toplink.essentials.sessions.UnitOfWork} will not refresh its registered objects.

see
#dontOnlyRefreshCacheIfNewerVersion

        setShouldOnlyRefreshCacheIfNewerVersion(true);
    
public voidpostInitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Post initializations after mappings are initialized.

        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(POST_INITIALIZED) || isInvalid()) {
            return;
        }

        setInitializationStage(POST_INITIALIZED);

        // Make sure that child is post initialized,
        // this initialize bottom up, unlike the two other phases that to top down.
        if (hasInheritance()) {
            for (Enumeration childEnum = getInheritancePolicy().getChildDescriptors().elements();
                     childEnum.hasMoreElements();) {
                ((ClassDescriptor)childEnum.nextElement()).postInitialize(session);
            }
        }

        // Allow mapping to perform post initialization.
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();

            // This causes post init to be called multiple times in inheritence.
            mapping.postInitialize(session);
            // PERF: computed if deferred locking is required.
            if (!shouldAcquireCascadedLocks()) {
                if ((mapping instanceof ForeignReferenceMapping) && (!((ForeignReferenceMapping)mapping).usesIndirection())) {
                    setShouldAcquireCascadedLocks(true);
                }
                if ((mapping instanceof AggregateObjectMapping) && ((AggregateObjectMapping)mapping).getDescriptor().shouldAcquireCascadedLocks()) {
                    setShouldAcquireCascadedLocks(true);
                }
            }
        }

        if (hasInheritance()) {
            getInheritancePolicy().postInitialize(session);
        }

        //PERF: Ensure that the identical primary key fields are used to avoid equals.
        for (int index = (getPrimaryKeyFields().size() - 1); index >= 0; index--) {
            DatabaseField primaryKeyField = (DatabaseField)getPrimaryKeyFields().get(index);
            int fieldIndex = getFields().indexOf(primaryKeyField);

            // Aggregate/agg-collections may not have a mapping for pk field.
            if (fieldIndex != -1) {
                primaryKeyField = (DatabaseField)getFields().get(fieldIndex);
                getPrimaryKeyFields().set(index, primaryKeyField);
            }
        }

        // Index and classify fields and primary key.
        // This is in post because it needs field classification defined in initializeMapping
        // this can come through a 1:1 so requires all descriptors to be initialized (mappings).
        // May 02, 2000 - Jon D.
        for (int index = 0; index < getFields().size(); index++) {
            DatabaseField field = getFields().elementAt(index);
            if (field.getType() == null) {
                DatabaseMapping mapping = getObjectBuilder().getMappingForField(field);
                if (mapping != null) {
                    field.setType(mapping.getFieldClassification(field));
                }
            }
            field.setIndex(index);
        }

        validateAfterInitialization(session);

        checkDatabase(session);
    
public voidpreInitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Allow the descriptor to initialize any dependancies on this session.

        //3934266 move validation to the policy allowing for this to be done in the sub policies.
        getObjectChangePolicy().initialize(session, this);

        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(PREINITIALIZED)) {
            return;
        }

        setInitializationStage(PREINITIALIZED);

        // Allow mapping pre init, must be done before validate.
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            try {
                DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
                mapping.preInitialize(session);
            } catch (DescriptorException exception) {
                session.getIntegrityChecker().handleError(exception);
            }
        }

        validateBeforeInitialization(session);

        preInitializeInheritancePolicy(session);
        
        // Make sure that parent is already preinitialized
        if (hasInheritance()) {
            // The default table will be set in this call once the duplicate
            // tables have been removed.
            getInheritancePolicy().preInitialize(session);
        } else {
            // This must be done now, after validate, before init anything else.
            setInternalDefaultTable();
        }

        verifyTableQualifiers(session.getDatasourcePlatform());
        initializeProperties(session);
        if (!isAggregateDescriptor()) {
            // Adjust before you initialize ...
            adjustMultipleTableInsertOrder();
            initializeMultipleTablePrimaryKeyFields();
        }

        getQueryManager().preInitialize(session);

    
protected voidpreInitializeInheritancePolicy(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Hook together the inheritance policy tree.

        if (isChildDescriptor() && (requiresInitialization())) {
            if (getInheritancePolicy().getParentClass().equals(getJavaClass())) {
                throw DescriptorException.parentClassIsSelf(this);
            }
            ClassDescriptor parentDescriptor = session.getDescriptor(getInheritancePolicy().getParentClass());
            parentDescriptor.getInheritancePolicy().addChildDescriptor(this);
            getInheritancePolicy().setParentDescriptor(parentDescriptor);
            parentDescriptor.preInitialize(session);
        }
    
protected voidprepareCascadeLockingPolicy(oracle.toplink.essentials.mappings.DatabaseMapping mapping)
INTERNAL:

        if (mapping.isPrivateOwned() && mapping.isForeignReferenceMapping()) {
            if (mapping.isCascadedLockingSupported()) {
                // Even if the mapping says it is supported in general, there 
                // may be conditions where it is not. Need the following checks.
                if (((ForeignReferenceMapping) mapping).hasCustomSelectionQuery()) {
                    throw ValidationException.unsupportedCascadeLockingMappingWithCustomQuery(mapping);
                } else if (isAggregateDescriptor() || isAggregateCollectionDescriptor()) {
                    throw ValidationException.unsupportedCascadeLockingDescriptor(this);
                } else {
                    mapping.prepareCascadeLockingPolicy();
                }
            } else {
                throw ValidationException.unsupportedCascadeLockingMapping(mapping);
            }
        }
    
public voidreInitializeJoinedAttributes()
INTERNAL: A user should not be setting which attributes to join or not to join after descriptor initialization; provided only for backwards compatibility.

        if (!isInitialized(POST_INITIALIZED)) {
            // wait until the descriptor gets initialized first
            return;
        }
        getObjectBuilder().initializeJoinedAttributes();
        if (hasInheritance()) {
            Vector children = getInheritancePolicy().getChildDescriptors();

            // use indeces to avoid synchronization.
            for (int i = 0; i < children.size(); i++) {
                InheritancePolicy child = (InheritancePolicy)children.elementAt(0);
                child.getDescriptor().reInitializeJoinedAttributes();
            }
        }
    
public voidrehashFieldDependancies(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Rehash any hashtables based on fields. This is used to clone descriptors for aggregates, which hammer field names, it is probably better not to hammer the field name and this should be refactored.

        getObjectBuilder().rehashFieldDependancies(session);

        for (Enumeration enumtr = getMappings().elements(); enumtr.hasMoreElements();) {
            ((DatabaseMapping)enumtr.nextElement()).rehashFieldDependancies(session);
        }
    
public oracle.toplink.essentials.mappings.DatabaseMappingremoveMappingForAttributeName(java.lang.String attributeName)
ADVANCED: Removes the locally defined mapping associated with a given attribute name. This can be used in a amendment method before the descriptor has been initialized.

        DatabaseMapping mapping = getMappingForAttributeName(attributeName);
        getMappings().remove(mapping);
        return mapping;
    
public voidremoveProperty(java.lang.String property)
PUBLIC: Remove the user defined property.

        getProperties().remove(property);
    
public booleanrequiresInitialization()
INTERNAL: Aggregate and Interface descriptors do not require initialization as they are cloned and initialized by each mapping.

        return !(isAggregateDescriptor());
    
protected voidselfValidationAfterInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Validate that the descriptor was defined correctly. This allows for checks to be done that require the descriptor initialization to be completed.

        // This has to be done after, because read subclasses must be initialized.
        if (!(hasInheritance() && (getInheritancePolicy().shouldReadSubclasses() || java.lang.reflect.Modifier.isAbstract(getJavaClass().getModifiers())))) {
            if (session.getIntegrityChecker().shouldCheckInstantiationPolicy()) {
                getInstantiationPolicy().buildNewInstance();
            }
        }
        getObjectBuilder().validate(session);
    
protected voidselfValidationBeforeInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Validate that the descriptor's non-mapping attribute are defined correctly.

        if (isChildDescriptor()) {
            ClassDescriptor parentDescriptor = session.getDescriptor(getInheritancePolicy().getParentClass());

            if (parentDescriptor == null) {
                session.getIntegrityChecker().handleError(DescriptorException.parentDescriptorNotSpecified(getInheritancePolicy().getParentClass().getName(), this));
            }
        } else {
            if (getTables().isEmpty() && (!isAggregateDescriptor())) {
                session.getIntegrityChecker().handleError(DescriptorException.tableNotSpecified(this));
            }
        }

        if (!isChildDescriptor() && !isAggregateDescriptor()) {
            if (getPrimaryKeyFieldNames().isEmpty()) {
                session.getIntegrityChecker().handleError(DescriptorException.primaryKeyFieldsNotSepcified(this));
            }
        }

        if ((getIdentityMapClass() == ClassConstants.NoIdentityMap_Class) && (getQueryManager().getDoesExistQuery().shouldCheckCacheForDoesExist())) {
            session.getIntegrityChecker().handleError(DescriptorException.identityMapNotSpecified(this));
        }

        if (((getSequenceNumberName() != null) && (getSequenceNumberField() == null)) || ((getSequenceNumberName() == null) && (getSequenceNumberField() != null))) {
            session.getIntegrityChecker().handleError(DescriptorException.sequenceNumberPropertyNotSpecified(this));
        }
    
protected voidsetAdditionalTablePrimaryKeyFields(oracle.toplink.essentials.internal.helper.DatabaseTable table, oracle.toplink.essentials.internal.helper.DatabaseField field1, oracle.toplink.essentials.internal.helper.DatabaseField field2)
INTERNAL: This is used to map the primary key field names in a multiple table descriptor.

        Map tableAdditionalPKFields = (Map)getAdditionalTablePrimaryKeyFields().get(table);
            
        if (tableAdditionalPKFields == null) {
            tableAdditionalPKFields = new HashMap(2);
            getAdditionalTablePrimaryKeyFields().put(table, tableAdditionalPKFields);
        }
            
        tableAdditionalPKFields.put(field1, field2);        
    
public voidsetAdditionalTablePrimaryKeyFields(java.util.Map additionalTablePrimaryKeyFields)
INTERNAL: This is used to map the primary key field names in a multiple table descriptor.

        this.additionalTablePrimaryKeyFields = additionalTablePrimaryKeyFields;
    
public voidsetAlias(java.lang.String alias)
PUBLIC: Set the alias

        this.alias = alias;
    
protected voidsetAllFields(java.util.Vector allFields)
INTERNAL: Set all the fields.

        this.allFields = allFields;
    
public voidsetAmendmentClass(java.lang.Class amendmentClass)
PUBLIC: Set the amendment class. The amendment method will be called on the class before initialization to allow for it to initialize the descriptor. The method must be a public static method on the class.

        this.amendmentClass = amendmentClass;
    
public voidsetAmendmentClassName(java.lang.String amendmentClassName)
INTERNAL: Return the amendment class name, used by the MW.

        this.amendmentClassName = amendmentClassName;
    
public voidsetAmendmentMethodName(java.lang.String amendmentMethodName)
PUBLIC: Set the amendment method. This will be called on the amendment class before initialization to allow for it to initialize the descriptor. The method must be a public static method on the class.

        this.amendmentMethodName = amendmentMethodName;
    
public voidsetCMPPolicy(oracle.toplink.essentials.descriptors.CMPPolicy newCMPPolicy)
ADVANCED: Set the cmp descriptor that holds EJB CMP specific information. This can only be specified when using CMP for bean class descriptors. This must be set explicitly if any setting need to be configured and before calling getCMPPolicy().

        cmpPolicy = newCMPPolicy;
        if (cmpPolicy != null){
            cmpPolicy.setDescriptor(this);
        }
    
public voidsetCacheInvalidationPolicy(oracle.toplink.essentials.descriptors.invalidation.CacheInvalidationPolicy policy)
PUBLIC: Set the Cache Invalidation Policy for this descriptor

param
CacheInvalidationPolicy
see
oracle.toplink.essentials.descriptors.invalidation.CacheInvalidationPolicy

        cacheInvalidationPolicy = policy;
    
public voidsetConstraintDependencies(java.util.Vector constraintDependencies)
ADVANCED: TopLink automatically orders database access through the foreign key information provided in 1:1 and 1:m mappings. In some case when 1:1 are not defined it may be required to tell the descriptor about a constraint, this defines that this descriptor has a foreign key constraint to another class and must be inserted after instances of the other class.

        this.constraintDependencies = constraintDependencies;
    
public voidsetCopyPolicy(oracle.toplink.essentials.descriptors.copying.CopyPolicy policy)
INTERNAL: Set the copy policy. This would be 'protected' but the EJB stuff in another package needs it to be public

        copyPolicy = policy;
        if (policy != null) {
            policy.setDescriptor(this);
        }
    
public voidsetDefaultTable(oracle.toplink.essentials.internal.helper.DatabaseTable defaultTable)
INTERNAL: The descriptors default table can be configured if the first table is not desired.

        this.defaultTable = defaultTable;
    
public voidsetDefaultTableName(java.lang.String defaultTableName)
PUBLIC: The descriptors default table can be configured if the first table is not desired.

        setDefaultTable(new DatabaseTable(defaultTableName));
    
public voidsetDescriptorType(int descriptorType)
ADVANCED: set the descriptor type (NORMAL by default, others include INTERFACE, AGGREGATE, AGGREGATE COLLECTION)

        this.descriptorType = descriptorType;
    
public voidsetDescriptorTypeValue(java.lang.String value)
INTERNAL: This method is explicitly used by the XML reader.

        if (value.equals("Aggregate collection")) {
            descriptorIsAggregateCollection();
        } else if (value.equals("Aggregate")) {
            descriptorIsAggregate();
        } else {
            descriptorIsNormal();
        }
    
public voidsetEventManager(oracle.toplink.essentials.descriptors.DescriptorEventManager eventManager)
INTERNAL: Set the event manager for the descriptor. The event manager is responsible for managing the pre/post selectors.

        this.eventManager = eventManager;
        if (eventManager != null) {
            eventManager.setDescriptor(this);
        }
    
public voidsetExistenceChecking(java.lang.String token)
INTERNAL: Set the existence check option from a string constant.

        getQueryManager().setExistenceCheck(token);
    
public voidsetFetchGroupManager(oracle.toplink.essentials.descriptors.FetchGroupManager fetchGroupManager)
PUBLIC: Set the fetch group manager for the descriptor. The fetch group manager is responsible for managing the fetch group behaviors and operations.

        this.fetchGroupManager = fetchGroupManager;
        if (fetchGroupManager != null) {
            //set the back reference
            fetchGroupManager.setDescriptor(this);
        }
    
public voidsetFields(java.util.Vector fields)
INTERNAL: Set the fields used by this descriptor.

        this.fields = fields;
    
public voidsetHasSimplePrimaryKey(boolean hasSimplePrimaryKey)
INTERNAL: PERF: Set if the primary key is simple (direct-mapped) to allow fast extraction.

        this.hasSimplePrimaryKey = hasSimplePrimaryKey;
    
public voidsetIdentityMapClass(java.lang.Class theIdentityMapClass)
PUBLIC: Set the class of identity map to be used by this descriptor. The default is the "FullIdentityMap".

        identityMapClass = theIdentityMapClass;
    
public voidsetIdentityMapSize(int identityMapSize)
PUBLIC: Set the size of the identity map to be used by this descriptor. The default is the 100.

        this.identityMapSize = identityMapSize;
    
public voidsetInheritancePolicy(oracle.toplink.essentials.descriptors.InheritancePolicy inheritancePolicy)
INTERNAL: Sets the inheritance policy.

        this.inheritancePolicy = inheritancePolicy;
        if (inheritancePolicy != null) {
            inheritancePolicy.setDescriptor(this);
        }
    
protected voidsetInitializationStage(int initializationStage)
INTERNAL:

        this.initializationStage = initializationStage;
    
public voidsetInstantiationPolicy(oracle.toplink.essentials.internal.descriptors.InstantiationPolicy instantiationPolicy)
INTERNAL: Sets the instantiation policy.

        this.instantiationPolicy = instantiationPolicy;
        if (instantiationPolicy != null) {
            instantiationPolicy.setDescriptor(this);
        }
    
public voidsetInternalDefaultTable()
INTERNAL: Set the default table if one if not already set. This method will extract the default table.

        if (getDefaultTable() == null) {
            setDefaultTable(extractDefaultTable());
        }
    
public voidsetInternalDefaultTable(oracle.toplink.essentials.internal.helper.DatabaseTable defaultTable)
INTERNAL: Set the default table if one if not already set. This method will set the table that is provided as the default.

        if (getDefaultTable() == null) {
            setDefaultTable(defaultTable);
        }
    
public voidsetIsIsolated(boolean isIsolated)
PUBLIC: Used to set if the class that this descriptor represents should be isolated from the shared cache. Note: Calling this method with true will also set the cacheSynchronizationType to DO_NOT_SEND_CHANGES since isolated objects cannot be sent by TopLink cache synchronization.

        this.isIsolated = isIsolated;
    
public voidsetJavaClass(java.lang.Class theJavaClass)
PUBLIC: Set the Java class that this descriptor maps. Every descriptor maps one and only one class.

        javaClass = theJavaClass;
    
public voidsetJavaClassName(java.lang.String theJavaClassName)
INTERNAL: Return the java class name, used by the MW.

        javaClassName = theJavaClassName;
    
public voidsetLockableMappings(java.util.List lockableMappings)
INTERNAL: Set the list of lockable mappings for this project This method is provided for CMP use. Normally, the lockable mappings are initialized at descriptor initialization time.

        this.lockableMappings = lockableMappings;
    
public voidsetMappings(java.util.Vector mappings)
INTERNAL: Set the mappings.

        // This is used from XML reader so must ensure that all mapping's descriptor has been set.
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();

            // For CR#2646, if the mapping already points to the parent descriptor then leave it.
            if (mapping.getDescriptor() == null) {
                mapping.setDescriptor(this);
            }
        }
        this.mappings = mappings;
    
public voidsetMultipleTableForeignKeyFieldNames(java.util.Vector associations)
INTERNAL: This method is used by the TopLink XML Deployment Descriptor to read and write these mappings

        Enumeration foreignKeys = associations.elements();
        while (foreignKeys.hasMoreElements()) {
            Association association = (Association)foreignKeys.nextElement();
            addMultipleTableForeignKeys((String)association.getKey(), (String)association.getValue(), true);
        }
    
protected voidsetMultipleTableForeignKeys(java.util.Map newValue)
INTERNAL:

see
#getMultipleTableForeignKeys

        this.multipleTableForeignKeys = newValue;
    
public voidsetMultipleTableInsertOrder(java.util.Vector newValue)
ADVANCED: Sets the Vector of DatabaseTables in the order which INSERTS should take place. This is normally computed correctly by TopLink, however in advanced cases in it may be overridden.

        this.multipleTableInsertOrder = newValue;
    
public voidsetMultipleTablePrimaryKeyFieldNames(java.util.Vector associations)
INTERNAL: This method is used by the TopLink XML Deployment Descriptor to read and write these mappings

        Enumeration foreignKeys = associations.elements();
        while (foreignKeys.hasMoreElements()) {
            Association association = (Association)foreignKeys.nextElement();
            addMultipleTableForeignKeys((String)association.getKey(), (String)association.getValue(), true);
        }
    
protected voidsetObjectBuilder(oracle.toplink.essentials.internal.descriptors.ObjectBuilder builder)
INTERNAL: Set the ObjectBuilder.

        objectBuilder = builder;
    
public voidsetObjectChangePolicy(oracle.toplink.essentials.descriptors.changetracking.ObjectChangePolicy policy)
PUBLIC: Set the ObjectChangePolicy for this descriptor.

        this.changePolicy = policy;
    
public voidsetOptimisticLockingPolicy(oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicy optimisticLockingPolicy)
PUBLIC: Set the OptimisticLockingPolicy. This can be one of the provided locking policies or a user defined policy.

see
VersionLockingPolicy
see
TimestampLockingPolicy
see
FieldsLockingPolicy

        this.optimisticLockingPolicy = optimisticLockingPolicy;
        if (optimisticLockingPolicy != null) {
            optimisticLockingPolicy.setDescriptor(this);
        }
    
public voidsetPrimaryKeyFieldName(java.lang.String fieldName)
PUBLIC: Specify the primary key field of the descriptors table. This should only be called if it is a singlton primary key field, otherwise addPrimaryKeyFieldName should be called. If the descriptor has many tables, this must be the primary key in all of the tables.

see
#addPrimaryKeyFieldName(String)

        addPrimaryKeyFieldName(fieldName);
    
public voidsetPrimaryKeyFieldNames(java.util.Vector primaryKeyFieldsName)
PUBLIC: User can specify a vector of all the primary key field names if primary key is composite.

see
#addPrimaryKeyFieldName(String)

        setPrimaryKeyFields(new ArrayList(primaryKeyFieldsName.size()));
        for (Enumeration keyEnum = primaryKeyFieldsName.elements(); keyEnum.hasMoreElements();) {
            addPrimaryKeyFieldName((String)keyEnum.nextElement());
        }
    
public voidsetPrimaryKeyFields(java.util.List thePrimaryKeyFields)
INTERNAL: Set the primary key fields

        primaryKeyFields = thePrimaryKeyFields;
    
public voidsetProperties(java.util.Map properties)
INTERNAL: Set the user defined properties.

        this.properties = properties;
    
public voidsetProperty(java.lang.String name, java.lang.Object value)
PUBLIC: Set the user defined property.

        getProperties().put(name, value);
    
public voidsetQueryKeys(java.util.Map queryKeys)
INTERNAL: Set the query keys.

        this.queryKeys = queryKeys;
    
public voidsetQueryManager(oracle.toplink.essentials.descriptors.DescriptorQueryManager queryManager)
INTERNAL: Set the query manager.

        this.queryManager = queryManager;
        if (queryManager != null) {
            queryManager.setDescriptor(this);
        }
    
public voidsetReadOnly()
PUBLIC: Set the descriptor to be read-only. Declaring a descriptor is read-only means that instances of the reference class will never be modified. Read-only descriptor is usually used in the unit of work to gain performance as there is no need for the registration, clone and merge for the read-only classes.

        setShouldBeReadOnly(true);
    
public voidsetSequenceNumberField(oracle.toplink.essentials.internal.helper.DatabaseField sequenceNumberField)
INTERNAL: Set the sequence number field.

        this.sequenceNumberField = sequenceNumberField;
    
public voidsetSequenceNumberFieldName(java.lang.String fieldName)
PUBLIC: Set the sequence number field name. This is the field in the descriptors table that needs its value to be generated. This is normally the primary key field of the descriptor.

        if (fieldName == null) {
            setSequenceNumberField(null);
        } else {
            setSequenceNumberField(new DatabaseField(fieldName));
        }
    
public voidsetSequenceNumberName(java.lang.String name)
PUBLIC: Set the sequence number name. This is the seq_name part of the row stored in the sequence table for this descriptor. If using Oracle native sequencing this is the name of the Oracle sequence object. If using Sybase native sequencing this name has no meaning, but should still be set for compatibility. The name does not have to be unique among descriptors, as having descriptors share sequences can improve pre-allocation performance.

        sequenceNumberName = name;
    
protected voidsetSessionName(java.lang.String sessionName)
INTERNAL: Set the name of the session local to this descriptor. This is used by the session broker.

        this.sessionName = sessionName;
    
public voidsetShouldAcquireCascadedLocks(boolean shouldAcquireCascadedLocks)
INTERNAL: PERF: Set if deferred locks should be used. This is determined based on if any relationships do not use indirection, but this provides a backdoor hook to force on if require because of events usage etc.

        this.shouldAcquireCascadedLocks = shouldAcquireCascadedLocks;
    
public voidsetShouldAlwaysConformResultsInUnitOfWork(boolean shouldAlwaysConformResultsInUnitOfWork)
PUBLIC: set if the descriptor is defined to always conform the results in unit of work in read query.

        this.shouldAlwaysConformResultsInUnitOfWork = shouldAlwaysConformResultsInUnitOfWork;
    
public voidsetShouldAlwaysRefreshCache(boolean shouldAlwaysRefreshCache)
PUBLIC: When the shouldAlwaysRefreshCache argument passed into this method is true, this method configures a Descriptor to always refresh the cache if data is received from the database by any query.

However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink will first look in the cache for the object. If the object is in the cache, the cached object is returned and data is not refreshed. To avoid cache hits, use the {@link #disableCacheHits} method.

Also note that the {@link oracle.toplink.essentials.sessions.UnitOfWork} will not refresh its registered objects.

Use this property with caution because it can lead to poor performance and may refresh on queries when it is not desired. Normally, if you require fresh data, it is better to configure a query with {@link oracle.toplink.essentials.queryframework.ObjectLevelReadQuery#refreshIdentityMapResult}. To ensure that refreshes are only done when required, use this method in conjunction with {@link #onlyRefreshCacheIfNewerVersion}.

When the shouldAlwaysRefreshCache argument passed into this method is false, this method ensures that a Descriptor is not configured to always refresh the cache if data is received from the database by any query.

see
#alwaysRefreshCache
see
#dontAlwaysRefreshCache

        this.shouldAlwaysRefreshCache = shouldAlwaysRefreshCache;
    
public voidsetShouldBeReadOnly(boolean shouldBeReadOnly)
PUBLIC: Define if the descriptor reference class is read-only

        this.shouldBeReadOnly = shouldBeReadOnly;
    
public voidsetShouldDisableCacheHits(boolean shouldDisableCacheHits)
PUBLIC: Set if cache hits on primary key read object queries should be disabled.

see
#alwaysRefreshCache()

        this.shouldDisableCacheHits = shouldDisableCacheHits;
    
public voidsetShouldOnlyRefreshCacheIfNewerVersion(boolean shouldOnlyRefreshCacheIfNewerVersion)
PUBLIC: When the shouldOnlyRefreshCacheIfNewerVersion argument passed into this method is true, this method configures a Descriptor to only refresh the cache if the data received from the database by a query is newer than the data in the cache (as determined by the optimistic locking field) and as long as one of the following is true:
  • the Descriptor was configured by calling {@link #alwaysRefreshCache} or {@link #alwaysRefreshCacheOnRemote},
  • the query was configured by calling {@link oracle.toplink.essentials.queryframework.ObjectLevelReadQuery#refreshIdentityMapResult}, or
  • the query was a call to {@link oracle.toplink.essentials.sessions.Session#refreshObject}

However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink will first look in the cache for the object. If the object is in the cache, the cached object is returned and data is not refreshed. To avoid cache hits, use the {@link #disableCacheHits} method.

Also note that the {@link oracle.toplink.essentials.sessions.UnitOfWork} will not refresh its registered objects.

When the shouldOnlyRefreshCacheIfNewerVersion argument passed into this method is false, this method ensures that a Descriptor is not configured to only refresh the cache if the data received from the database by a query is newer than the data in the cache (as determined by the optimistic locking field).

see
#onlyRefreshCacheIfNewerVersion
see
#dontOnlyRefreshCacheIfNewerVersion

        this.shouldOnlyRefreshCacheIfNewerVersion = shouldOnlyRefreshCacheIfNewerVersion;
    
public voidsetShouldOrderMappings(boolean shouldOrderMappings)
PUBLIC: This is set to turn off the ordering of mappings. By Default this is set to true. By ordering the mappings TopLink insures that object are merged in the right order. If the order of the mappings needs to be specified by the developer then set this to false and TopLink will use the order that the mappings were added to the descriptor

        this.shouldOrderMappings = shouldOrderMappings;
    
public voidsetShouldRegisterResultsInUnitOfWork(boolean shouldRegisterResultsInUnitOfWork)
INTERNAL: Set to false to have queries conform to a UnitOfWork without registering any additional objects not already in that UnitOfWork.

see
#shouldRegisterResultsInUnitOfWork
bug
2612601

        this.shouldRegisterResultsInUnitOfWork = shouldRegisterResultsInUnitOfWork;
    
public voidsetTableName(java.lang.String tableName)
PUBLIC: Specify the table name for the class of objects the receiver describes. If the table has a qualifier it should be specified using the dot notation, (i.e. "userid.employee"). This method is used for single table.

        if (getTables().isEmpty()) {
            addTableName(tableName);
        } else {
            throw DescriptorException.onlyOneTableCanBeAddedWithThisMethod(this);
        }
    
public voidsetTableNames(java.util.Vector tableNames)
PUBLIC: Specify the all table names for the class of objects the receiver describes. If the table has a qualifier it should be specified using the dot notation, (i.e. "userid.employee"). This method is used for multiple tables

        setTables(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(tableNames.size()));
        for (Enumeration tableEnum = tableNames.elements(); tableEnum.hasMoreElements();) {
            addTableName((String)tableEnum.nextElement());
        }
    
public voidsetTableQualifier(java.lang.String tableQualifier)
PUBLIC: Set the table Qualifier for this descriptor. This table creator will be used for all tables in this descriptor

        for (Enumeration enumtr = getTables().elements(); enumtr.hasMoreElements();) {
            DatabaseTable table = (DatabaseTable)enumtr.nextElement();
            table.setTableQualifier(tableQualifier);
        }
    
public voidsetTables(java.util.Vector theTables)
INTERNAL: Sets the tables

        tables = theTables;
    
public voidsetWrapperPolicy(oracle.toplink.essentials.descriptors.WrapperPolicy wrapperPolicy)
ADVANCED: Sets the WrapperPolicy for this descriptor. This advacned feature can be used to wrap objects with other classes such as CORBA TIE objects or EJBs.

        this.wrapperPolicy = wrapperPolicy;

        // For bug 2766379 must be able to set the wrapper policy back to default
        // which is null.
        if (wrapperPolicy != null) {
            wrapperPolicy.setDescriptor(this);
        }
    
public booleanshouldAcquireCascadedLocks()
INTERNAL: PERF: Return if deferred locks should be used. Used to optimize read locking. This is determined based on if any relationships do not use indirection.

        return shouldAcquireCascadedLocks;
    
public booleanshouldAlwaysConformResultsInUnitOfWork()
PUBLIC: Return if the descriptor is defined to always conform the results in unit of work in read query.

        return shouldAlwaysConformResultsInUnitOfWork;
    
public booleanshouldAlwaysRefreshCache()
PUBLIC: This method returns true if the Descriptor is configured to always refresh the cache if data is received from the database by any query. Otherwise, it returns false.

see
#setShouldAlwaysRefreshCache

        return shouldAlwaysRefreshCache;
    
public booleanshouldBeReadOnly()
PUBLIC: Return if the descriptor reference class is defined as read-only

        return shouldBeReadOnly;
    
public booleanshouldDisableCacheHits()
PUBLIC: Return if for cache hits on primary key read object queries to be disabled.

see
#disableCacheHits()

        return shouldDisableCacheHits;
    
public booleanshouldOnlyRefreshCacheIfNewerVersion()
PUBLIC: This method returns true if the Descriptor is configured to only refresh the cache if the data received from the database by a query is newer than the data in the cache (as determined by the optimistic locking field). Otherwise, it returns false.

see
#setShouldOnlyRefreshCacheIfNewerVersion

        return shouldOnlyRefreshCacheIfNewerVersion;
    
public booleanshouldOrderMappings()
INTERNAL: Return if mappings should be ordered or not. By default this is set to true to prevent attributes from being merged in the wrong order

        return shouldOrderMappings;
    
public booleanshouldRegisterResultsInUnitOfWork()
INTERNAL: Allows one to do conforming in a UnitOfWork without registering. Queries executed on a UnitOfWork will only return working copies for objects that have already been registered.

Extreme care should be taken in using this feature, for a user will get back a mix of registered and original (unregistered) objects.

Best used with a WrapperPolicy where invoking on an object will trigger its registration (CMP). Without a WrapperPolicy {@link oracle.toplink.essentials.sessions.UnitOfWork#registerExistingObject registerExistingObject} should be called on any object that you intend to change.

return
true by default.
see
#setShouldRegisterResultsInUnitOfWork
see
oracle.toplink.essentials.queryframework.ObjectLevelReadQuery#shouldRegisterResultsInUnitOfWork
bug
2612601

        return shouldRegisterResultsInUnitOfWork;
    
public booleanshouldUseCacheIdentityMap()
PUBLIC: Return true if this descriptor is using CacheIdentityMap

        return (getIdentityMapClass() == ClassConstants.CacheIdentityMap_Class);
    
public booleanshouldUseFullIdentityMap()
PUBLIC: Return true if this descriptor is using FullIdentityMap

        return (getIdentityMapClass() == ClassConstants.FullIdentityMap_Class);
    
public booleanshouldUseHardCacheWeakIdentityMap()
PUBLIC: Return true if this descriptor is using HardCacheWeakIdentityMap.

        return (getIdentityMapClass() == ClassConstants.HardCacheWeakIdentityMap_Class);
    
public booleanshouldUseNoIdentityMap()
PUBLIC: Return true if this descriptor is using NoIdentityMap

        return (getIdentityMapClass() == ClassConstants.NoIdentityMap_Class);
    
public booleanshouldUseSoftCacheWeakIdentityMap()
PUBLIC: Return true if this descriptor is using SoftCacheWeakIdentityMap.

        return (getIdentityMapClass() == ClassConstants.SoftCacheWeakIdentityMap_Class);
    
public booleanshouldUseWeakIdentityMap()
PUBLIC: Return true if this descriptor is using WeakIdentityMap

        return (getIdentityMapClass() == ClassConstants.WeakIdentityMap_Class);
    
public java.lang.StringtoString()
PUBLIC: Returns a brief string representation of the receiver.

        return Helper.getShortClassName(getClass()) + "(" + getJavaClassName() + " --> " + getTables() + ")";
    
protected voidtoggleAdditionalTablePrimaryKeyFields(oracle.toplink.essentials.internal.helper.DatabaseTable targetTable, oracle.toplink.essentials.internal.helper.DatabaseTable sourceTable)
INTERNAL: This method will be called in the case where the foreign key field is in the target table which is before the source table. In most cases, this would be when the fk is on the primary table (that is, true multiple table foreign key field)

        Map targetTableAdditionalPKFields = (Map)getAdditionalTablePrimaryKeyFields().get(targetTable);
            
        if (targetTableAdditionalPKFields != null) {
            Iterator e = targetTableAdditionalPKFields.keySet().iterator();
        
            while (e.hasNext()) {
                DatabaseField sourceField = (DatabaseField)e.next();
                DatabaseField targetField = (DatabaseField) targetTableAdditionalPKFields.get(sourceField);
            
                setAdditionalTablePrimaryKeyFields(sourceTable, targetField, sourceField);
            }
            
            targetTableAdditionalPKFields.clear();
        }
    
public voiduseCacheIdentityMap()
PUBLIC: Set the class of identity map to be the cache identity map. This map caches the LRU instances read from the database. The default in JDK1.1 is "FullIdentityMap", in JDK1.2 it is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.CacheIdentityMap_Class);
    
public voiduseCloneCopyPolicy()
PUBLIC: Specifies that the creation of clones within a unit of work is done by sending the #clone() method to the original object. The #clone() method must return a logical shallow copy of the original object. This can be used if the default mechanism of creating a new instance does not handle the object's non-persistent attributes correctly.

see
#useCloneCopyPolicy(String)

        useCloneCopyPolicy("clone");
    
public voiduseCloneCopyPolicy(java.lang.String cloneMethodName)
PUBLIC: Specifies that the creation of clones within a unit of work is done by sending the cloneMethodName method to the original object. This method must return a logical shallow copy of the original object. This can be used if the default mechanism of creating a new instance does not handle the object's non-persistent attributes correctly.

see
#useCloneCopyPolicy()

        CloneCopyPolicy policy = new CloneCopyPolicy();
        policy.setMethodName(cloneMethodName);
        setCopyPolicy(policy);
    
public voiduseDefaultConstructorInstantiationPolicy()
PUBLIC: Use the default constructor to create new instances of objects built from the database. This is the default. The descriptor's class must either define a default constructor or define no constructors at all.

see
#useMethodInstantiationPolicy(String)
see
#useFactoryInstantiationPolicy(Class, String)
see
#useFactoryInstantiationPolicy(Class, String, String)
see
#useFactoryInstantiationPolicy(Object, String)

        getInstantiationPolicy().useDefaultConstructorInstantiationPolicy();
    
public voiduseFactoryInstantiationPolicy(java.lang.Class factoryClass, java.lang.String methodName)
PUBLIC: Use an object factory to create new instances of objects built from the database. The methodName is the name of the method that will be invoked on the factory. When invoked, it must return a new instance of the descriptor's class. The factory will be created by invoking the factoryClass's default constructor.

see
#useDefaultConstructorInstantiationPolicy()
see
#useMethodInstantiationPolicy(String)
see
#useFactoryInstantiationPolicy(Class, String, String)
see
#useFactoryInstantiationPolicy(Object, String)

        getInstantiationPolicy().useFactoryInstantiationPolicy(factoryClass, methodName);
    
public voiduseFactoryInstantiationPolicy(java.lang.String factoryClassName, java.lang.String methodName)
INTERNAL: Set the factory class name, used by the MW.

        getInstantiationPolicy().useFactoryInstantiationPolicy(factoryClassName, methodName);
    
public voiduseFactoryInstantiationPolicy(java.lang.Class factoryClass, java.lang.String methodName, java.lang.String factoryMethodName)
PUBLIC: Use an object factory to create new instances of objects built from the database. The factoryMethodName is a static method declared by the factoryClass. When invoked, it must return an instance of the factory. The methodName is the name of the method that will be invoked on the factory. When invoked, it must return a new instance of the descriptor's class.

see
#useDefaultConstructorInstantiationPolicy()
see
#useFactoryInstantiationPolicy(Class, String)
see
#useFactoryInstantiationPolicy(Object, String)
see
#useMethodInstantiationPolicy(String)

        getInstantiationPolicy().useFactoryInstantiationPolicy(factoryClass, methodName, factoryMethodName);
    
public voiduseFactoryInstantiationPolicy(java.lang.String factoryClassName, java.lang.String methodName, java.lang.String factoryMethodName)
INTERNAL: Set the factory class name, used by the MW.

        getInstantiationPolicy().useFactoryInstantiationPolicy(factoryClassName, methodName, factoryMethodName);
    
public voiduseFactoryInstantiationPolicy(java.lang.Object factory, java.lang.String methodName)
PUBLIC: Use an object factory to create new instances of objects built from the database. The methodName is the name of the method that will be invoked on the factory. When invoked, it must return a new instance of the descriptor's class.

see
#useDefaultConstructorInstantiationPolicy()
see
#useMethodInstantiationPolicy(String)
see
#useFactoryInstantiationPolicy(Class, String)
see
#useFactoryInstantiationPolicy(Class, String, String)

        getInstantiationPolicy().useFactoryInstantiationPolicy(factory, methodName);
    
public voiduseFullIdentityMap()
PUBLIC: Set the class of identity map to be the full identity map. This map caches all instances read and grows to accomodate them. The default is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.FullIdentityMap_Class);
    
public voiduseHardCacheWeakIdentityMap()
PUBLIC: Set the class of identity map to be the hard cache weak identity map. This map uses weak references to only cache object in-memory. It also includes a secondary fixed sized soft cache to improve caching performance. This is provided because some Java VM's do not implement soft references correctly. The default is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.HardCacheWeakIdentityMap_Class);
    
public voiduseInstantiationCopyPolicy()
PUBLIC: Specifies that the creation of clones within a unit of work is done by building a new instance using the technique indicated by the descriptor's instantiation policy (which by default is to use the the default constructor). This new instance is then populated by using the descriptor's mappings to copy attributes from the original to the clone. This is the default. If another mechanism is desired the copy policy allows for a clone method to be called.

see
#useCloneCopyPolicy()
see
#useCloneCopyPolicy(String)
see
#useDefaultConstructorInstantiationPolicy()
see
#useMethodInstantiationPolicy(String)
see
#useFactoryInstantiationPolicy(Class, String)
see
#useFactoryInstantiationPolicy(Class, String, String)
see
#useFactoryInstantiationPolicy(Object, String)

        setCopyPolicy(new InstantiationCopyPolicy());
    
public voiduseMethodInstantiationPolicy(java.lang.String staticMethodName)
PUBLIC: Use the specified static method to create new instances of objects built from the database. This method must be statically declared by the descriptor's class, and it must return a new instance of the descriptor's class.

see
#useDefaultConstructorInstantiationPolicy()
see
#useFactoryInstantiationPolicy(Class, String)
see
#useFactoryInstantiationPolicy(Class, String, String)
see
#useFactoryInstantiationPolicy(Object, String)

        getInstantiationPolicy().useMethodInstantiationPolicy(staticMethodName);
    
public voiduseNoIdentityMap()
PUBLIC: Set the class of identity map to be the no identity map. This map does no caching. The default is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.NoIdentityMap_Class);
    
public voiduseSoftCacheWeakIdentityMap()
PUBLIC: Set the class of identity map to be the soft cache weak identity map. The SoftCacheIdentityMap holds a fixed number of objects is memory (using SoftReferences) to improve caching. The default is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.SoftCacheWeakIdentityMap_Class);
    
public voiduseTimestampLocking(java.lang.String writeLockFieldName)
PUBLIC: Use the Timestamps locking policy and storing the value in the cache key #see useVersionLocking(String)

        useTimestampLocking(writeLockFieldName, true);
    
public voiduseTimestampLocking(java.lang.String writeLockFieldName, boolean shouldStoreInCache)
PUBLIC: Set the locking policy to use timestamp version locking. This updates the timestamp field on all updates, first comparing that the field has not changed to detect locking conflicts. Note: many database have limited precision of timestamps which can be an issue is highly concurrent systems. The parameter 'shouldStoreInCache' configures the version lock value to be stored in the cache or in the object. Note: if using a stateless model where the object can be passed to a client and then later updated in a different transaction context, then the version lock value should not be stored in the cache, but in the object to ensure it is the correct value for that object.

see
VersionLockingPolicy

        TimestampLockingPolicy policy = new TimestampLockingPolicy(writeLockFieldName);
        if (shouldStoreInCache) {
            policy.storeInCache();
        } else {
            policy.storeInObject();
        }
        setOptimisticLockingPolicy(policy);
    
public voiduseVersionLocking(java.lang.String writeLockFieldName)
PUBLIC: Default to use the version locking policy and storing the value in the cache key #see useVersionLocking(String)

        useVersionLocking(writeLockFieldName, true);
    
public voiduseVersionLocking(java.lang.String writeLockFieldName, boolean shouldStoreInCache)
PUBLIC: Set the locking policy to use numeric version locking. This updates the version field on all updates, first comparing that the field has not changed to detect locking conflicts. The parameter 'shouldStoreInCache' configures the version lock value to be stored in the cache or in the object. Note: if using a stateless model where the object can be passed to a client and then later updated in a different transaction context, then the version lock value should not be stored in the cache, but in the object to ensure it is the correct value for that object.

see
TimestampLockingPolicy

        VersionLockingPolicy policy = new VersionLockingPolicy(writeLockFieldName);
        if (shouldStoreInCache) {
            policy.storeInCache();
        } else {
            policy.storeInObject();
        }
        setOptimisticLockingPolicy(policy);
    
public voiduseWeakIdentityMap()
PUBLIC: Set the class of identity map to be the weak identity map. The default is the "SoftCacheWeakIdentityMap".

        setIdentityMapClass(ClassConstants.WeakIdentityMap_Class);
    
public booleanusesOptimisticLocking()
PUBLIC: Return true if the receiver uses write (optimistic) locking.

        return (optimisticLockingPolicy != null);
    
public booleanusesSequenceNumbers()
PUBLIC: Return true if the receiver uses sequence numbers.

        return ((getSequenceNumberField() != null) && (getSequenceNumberName() != null));
    
public booleanusesVersionLocking()
PUBLIC: Return true if the receiver uses version optimistic locking.

        return (usesOptimisticLocking() && (getOptimisticLockingPolicy() instanceof VersionLockingPolicy));
    
protected voidvalidateAfterInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Validate the entire post-initialization descriptor.

        selfValidationAfterInitialization(session);
        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
            ((DatabaseMapping)mappings.nextElement()).validateAfterInitialization(session);
        }
    
protected voidvalidateBeforeInitialization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Validate the entire pre-initialization descriptor.

        selfValidationBeforeInitialization(session);
        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
            ((DatabaseMapping)mappings.nextElement()).validateBeforeInitialization(session);
        }
    
protected voidvalidateMappingType(oracle.toplink.essentials.mappings.DatabaseMapping mapping)

        if (!(mapping.isRelationalMapping())) {
            throw DescriptorException.invalidMappingType(mapping);
        }
    
protected voidverifyTableQualifiers(oracle.toplink.essentials.internal.databaseaccess.Platform platform)
INTERNAL: Check that the qualifier on the table names are properly set.

        DatabaseTable table;
        Enumeration tableEnumeration;
        String tableQualifier = platform.getTableQualifier();

        if (tableQualifier.length() == 0) {
            return;
        }

        tableEnumeration = getTables().elements();
        while (tableEnumeration.hasMoreElements()) {
            table = (DatabaseTable)tableEnumeration.nextElement();
            if (table.getTableQualifier().length() == 0) {
                table.setTableQualifier(tableQualifier);
            }
        }