FileDocCategorySizeDatePackage
DescriptorQueryManager.javaAPI DocGlassfish v2 API53771Tue May 22 16:54:16 BST 2007oracle.toplink.essentials.descriptors

DescriptorQueryManager

public class DescriptorQueryManager extends Object implements Serializable, Cloneable

Purpose: The query manager allows for the database opperations that TopLink performs to be customized by the application. For each descriptor a query can be given that controls how a operation will occur. A common example is if the application requires a stored procedure to be used to insert the object, it can override the SQL call in the insert query that TopLink will use to insert the object. Queries can be customized to extend TopLink behavior, access non-relational data or use stored procedures or customized SQL calls.

The queries that can be customized include:

  • insertQuery - used to insert the object
  • updateQuery - used to update the object
  • readObjectQuery - used to read a single object by primary key
  • readAllQuery - used to read all of the objects of the class
  • doesExistQuery - used to determine whether an insert or update should occur
  • deleteQuery - used to delete the object
see
ClassDescriptor

Fields Summary
protected transient InsertObjectQuery
insertQuery
protected transient UpdateObjectQuery
updateQuery
protected transient ReadObjectQuery
readObjectQuery
protected transient ReadAllQuery
readAllQuery
protected transient DeleteObjectQuery
deleteQuery
protected DoesExistQuery
doesExistQuery
protected ClassDescriptor
descriptor
protected boolean
hasCustomMultipleTableJoinExpression
protected transient Expression
additionalJoinExpression
protected transient Expression
multipleTableJoinExpression
protected transient Map
queries
protected transient Map
tablesJoinExpressions
Constructors Summary
public DescriptorQueryManager()
INTERNAL: Initialize the state of the descriptor query manager

        this.queries = new HashMap(5);
        setDoesExistQuery(new DoesExistQuery());// Always has a does exist.
    
Methods Summary
public voidaddQuery(java.lang.String name, DatabaseQuery query)
PUBLIC: Add the query to the descriptor queries with the given name

param
name This is the name of the query. It will be set on the query and used to look it up.
param
query This is the query that will be added. If the query being added has parameters, the existing list of queries will be checked for matching queries. If a matching query exists, it will be replaced.

        query.setName(name);
        addQuery(query);
    
public synchronized voidaddQuery(DatabaseQuery query)
PUBLIC: Add the query to the session queries

param
query DatabaseQuery This is the query that will be added. If the query being added has parameters, the existing list of queries will be checked for matching queries. If a matching query exists, it will be replaced.

        if (query instanceof ObjectLevelReadQuery && (((ObjectLevelReadQuery)query).getReferenceClassName() == null)) {
            ((ObjectLevelReadQuery)query).setReferenceClassName(getDescriptor().getJavaClassName());

            // try to set the reference ClassNotFoundException since it should only happen on the MW in which
            // case we will lazily initialize the reference class at a later point.
            try {
                ((ObjectLevelReadQuery)query).setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }

            //this is an optimization
            query.setDescriptor(getDescriptor());
        }

        // Add query has been synchronized for bug 3355199.
        // Additionally code has been added to ensure that the same query is not added twice.
        Vector queriesByName = (Vector)getQueries().get(query.getName());
        if (queriesByName == null) {
            // lazily create Vector in Hashtable.
            queriesByName = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
            getQueries().put(query.getName(), queriesByName);
        } else {
            int argumentTypesSize = 0;
            if (query.getArguments() != null) {
                argumentTypesSize = query.getArguments().size();
            }
            Vector argumentTypes = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(argumentTypesSize);
            for (int i = 0; i < argumentTypesSize; i++) {
                argumentTypes.addElement(query.getArgumentTypeNames().elementAt(i));
            }

            // Search for a query with the same parameters and replace it if one is found
            for (int i = 0; i < queriesByName.size(); i++) {
                DatabaseQuery currentQuery = (DatabaseQuery)queriesByName.elementAt(i);

                // Here we are checking equality instead of assignability.  If you look at getQuery()
                // it is the other way around.
                // The reason we do this is we are replacing a query and we want to make sure we are
                // replacing the exact same one. - TW
                if (argumentTypes.equals(currentQuery.getArgumentTypeNames())) {
                    queriesByName.remove(i);
                    queriesByName.add(i, query);
                    return;
                }
            }
        }
        queriesByName.add(query);
    
public voidassumeExistenceForDoesExist()
PUBLIC: Assume that if the objects primary key does not include null then it must exist. This may be used if the application guarantees or does not care about the existence check.

        getDoesExistQuery().assumeExistenceForDoesExist();
    
public voidassumeNonExistenceForDoesExist()
PUBLIC: Assume that the object does not exist. This may be used if the application guarantees or does not care about the existence check. This will always force an insert to be called.

        getDoesExistQuery().assumeNonExistenceForDoesExist();
    
public voidcheckCacheForDoesExist()
PUBLIC: Default behavior. Assume that if the objects primary key does not include null and it is in the cache, then is must exist.

        getDoesExistQuery().checkCacheForDoesExist();
    
public voidcheckDatabaseForDoesExist()
PUBLIC: Perform does exist check on the database

        getDoesExistQuery().checkDatabaseForDoesExist();
    
public java.lang.Objectclone()
INTERNAL: Clone the query manager

        DescriptorQueryManager manager = null;
        try {
            manager = (DescriptorQueryManager)super.clone();
        } catch (Exception exception) {
            ;
        }

        // Bug 3037701 - clone the queries
        manager.setQueries(new Hashtable(getQueries().size()));
        Iterator iterator = queries.values().iterator();
        while (iterator.hasNext()) {
            Iterator queriesForKey = ((Vector)iterator.next()).iterator();
            while (queriesForKey.hasNext()) {
                DatabaseQuery initialQuery = (DatabaseQuery)queriesForKey.next();
                DatabaseQuery clonedQuery = (DatabaseQuery)initialQuery.clone();
                clonedQuery.setDescriptor(manager.getDescriptor());
                manager.addQuery(clonedQuery);
            }
        }
        manager.setDoesExistQuery((DoesExistQuery)getDoesExistQuery().clone());
        if (getReadAllQuery() != null) {
            manager.setReadAllQuery((ReadAllQuery)getReadAllQuery().clone());
        }
        if (getReadObjectQuery() != null) {
            manager.setReadObjectQuery((ReadObjectQuery)getReadObjectQuery().clone());
        }
        if (getUpdateQuery() != null) {
            manager.setUpdateQuery((UpdateObjectQuery)getUpdateQuery().clone());
        }
        if (getInsertQuery() != null) {
            manager.setInsertQuery((InsertObjectQuery)getInsertQuery().clone());
        }
        if (getDeleteQuery() != null) {
            manager.setDeleteQuery((DeleteObjectQuery)getDeleteQuery().clone());
        }

        return manager;
    
public booleancontainsQuery(java.lang.String queryName)
PUBLIC: Return true if the query is defined on the session

        return queries.containsKey(queryName);
    
public voidconvertClassNamesToClasses(java.lang.ClassLoader classLoader)
INTERNAL: Convert all the class-name-based settings in this Query Manager to actual class-based settings This method is implemented by subclasses as necessary.

param
classLoader

        Iterator queryVectors = getQueries().values().iterator();
        while (queryVectors.hasNext()){
            Iterator queries = ((Vector)queryVectors.next()).iterator();;
            while (queries.hasNext()){
                ((DatabaseQuery)queries.next()).convertClassNamesToClasses(classLoader);
            }
        }
    
public ExpressiongetAdditionalJoinExpression()
ADVANCED: Returns the join expression that should be appended to all of the descriptors expressions Contains any multiple table or inheritance dependencies

        return additionalJoinExpression;
    
public java.util.VectorgetAllQueries()
PUBLIC: Return the pre-defined queries for the descriptor. The Vector returned contains all queries for this descriptor.

see
#getQueries()

        Vector allQueries = new Vector();
        for (Iterator vectors = getQueries().values().iterator(); vectors.hasNext();) {
            allQueries.addAll((Vector)vectors.next());
        }
        return allQueries;
    
public CallgetDeleteCall()
ADVANCED: Return the receiver's delete call. This allows the user to override the delete operation.

        if (getDeleteQuery() == null) {
            return null;
        }
        return getDeleteQuery().getDatasourceCall();
    
public DeleteObjectQuerygetDeleteQuery()
ADVANCED: Return the receiver's delete query. This should be an instance of a valid subclass of DeleteObjectQuery. If specified this is used by the descriptor to delete itself and its private parts from the database. This gives the user the ability to define exactly how to delete the data from the database, or access data external from the database or from some other framework.

        return deleteQuery;
    
public java.lang.StringgetDeleteSQLString()
ADVANCED: Return the receiver's delete SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields.

Example, "delete from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (getDeleteQuery() == null) {
            return null;
        }

        return getDeleteQuery().getSQLString();
    
protected ClassDescriptorgetDescriptor()
INTERNAL: Return the descriptor associated with this descriptor query manager

        return descriptor;
    
public CallgetDoesExistCall()
ADVANCED: Return the receiver's does-exist call. This allows the user to override the does-exist operation.

        if (getDoesExistQuery() == null) {
            return null;
        }
        return getDoesExistQuery().getDatasourceCall();
    
public DoesExistQuerygetDoesExistQuery()
ADVANCED: Return the receiver's does exist query. This should be an instance of a valid subclass of DoesExistQuery. If specified this is used by the descriptor to query existence of an object in the database. This gives the user the ability to define exactly how to query existence from the database, or access data external from the database or from some other framework.

        return doesExistQuery;
    
public java.lang.StringgetDoesExistSQLString()
ADVANCED: Return the receiver's does exist SQL string. This allows the user to override the SQL generated by TopLink, with there own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields. This must return null if the object does not exist, otherwise return a database row.

Example, "select EMPLOYEE_ID from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (getDoesExistQuery() == null) {
            return null;
        }

        return getDoesExistQuery().getSQLString();
    
public java.lang.StringgetExistenceCheck()
INTERNAL: This method is explicitly used by the Builder only.

        if (getDoesExistQuery().shouldAssumeExistenceForDoesExist()) {
            return "Assume existence";
        } else if (getDoesExistQuery().shouldAssumeNonExistenceForDoesExist()) {
            return "Assume non-existence";
        } else if (getDoesExistQuery().shouldCheckCacheForDoesExist()) {
            return "Check cache";
        } else if (getDoesExistQuery().shouldCheckDatabaseForDoesExist()) {
            return "Check database";
        } else {
            // Default.
            return "Check cache";
        }
    
public CallgetInsertCall()
ADVANCED: Return the receiver's insert call. This allows the user to override the insert operation.

        if (getInsertQuery() == null) {
            return null;
        }
        return getInsertQuery().getDatasourceCall();
    
public InsertObjectQuerygetInsertQuery()
ADVANCED: Return the receiver's insert query. This should be an instance of a valid subclass of InsertObjectQuery. If specified this is used by the descriptor to insert itself into the database. If the receiver uses sequence numbers, this query must return the updated sequence value. This gives the user the ability to define exactly how to insert the data into the database, or access data externel from the database or from some other framework.

        return insertQuery;
    
public java.lang.StringgetInsertSQLString()
ADVANCED: Return the receiver's insert SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields.

Example, "insert into EMPLOYEE (F_NAME, L_NAME) values (#F_NAME, #L_NAME)".

        if (getInsertQuery() == null) {
            return null;
        }

        return getInsertQuery().getSQLString();
    
public DatabaseQuerygetLocalQuery(java.lang.String name, java.util.Vector arguments)
INTENAL: Return the query from the set of pre-defined queries with the given name and argument types. This allows for common queries to be pre-defined, reused and executed by name. Only returns those queries locally defined, not superclass's queries If only one query exists, it will be returned regardless of the arguments. If multiple queries exist, the first query that has corresponding argument types will be returned

see
#getQuery(String)

        Vector queries = (Vector)getQueries().get(name);

        if (queries == null){
            return null;
        }
        
        // Short circuit the simple, most common case of only one query.
        if (queries.size() == 1) {
            return (DatabaseQuery)queries.firstElement();
        }

        // CR#3754; Predrag; mar 19/2002;
        // We allow multiple named queries with the same name but
        // different argument set; we can have only one query with
        // no arguments; Vector queries is not sorted;
        // When asked for the query with no parameters the
        // old version did return the first query - wrong: 
        // return (DatabaseQuery) queries.firstElement();
       int argumentTypesSize = 0;
        if (arguments != null) {
            argumentTypesSize = arguments.size();
        }
        Vector argumentTypes = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(argumentTypesSize);
        for (int i = 0; i < argumentTypesSize; i++) {
            argumentTypes.addElement(arguments.elementAt(i).getClass());
        }
        for (Enumeration queriesEnum = queries.elements(); queriesEnum.hasMoreElements();) {
            DatabaseQuery query = (DatabaseQuery)queriesEnum.nextElement();

            // BUG#2698755
            // This check was backward, we default the type to Object
            // Was checking Object is decendent of String not other way.
            if (Helper.areTypesAssignable(query.getArgumentTypes(), argumentTypes)) {
                return query;
            }
        }

        return null;

    
public ExpressiongetMultipleTableJoinExpression()
ADVANCED: This is normally generated for descriptors that have multiple tables. However, if the additional table does not reference the primary tables primary key, this expression may be set directly.

        return multipleTableJoinExpression;
    
public oracle.toplink.essentials.descriptors.DescriptorQueryManagergetParentDescriptorQueryManager()
INTERNAL: Get the parent DescriptorQueryManager. Caution must be used in using this method as it expects the descriptor to have inheritance. Calling this when the descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.

        return getDescriptor().getInheritancePolicy().getParentDescriptor().getQueryManager();
    
public java.util.MapgetQueries()
PUBLIC: Return the pre-defined queries for the descriptor. The Hashtable returned contains Vectors of queries.

see
#getAllQueries()

        return queries;
    
public DatabaseQuerygetQuery(java.lang.String queryName)
PUBLIC: Return the query name from the set of pre-defined queries If only one query exists with this name, it will be returned. If there are multiple queries of this name, this method will search for a query with no arguments and return the first one it finds.

see
#getQuery(String, Vector)

        return getQuery(queryName, null);
    
public DatabaseQuerygetQuery(java.lang.String name, java.util.Vector arguments)
PUBLIC: Return the query from the set of pre-defined queries with the given name and argument types. This allows for common queries to be pre-defined, reused and executed by name. This method should be used if the Session has multiple queries with the same name but different arguments. If only one query exists, it will be returned regardless of the arguments. If multiple queries exist, the first query that has corresponding argument types will be returned

see
#getQuery(String)

        DatabaseQuery query = getLocalQuery(name, arguments);

        // CR#3711: Check if a query with the same name exists for this descriptor.  
        // If not, recursively check descriptors of parent classes.  If nothing is 
        // found in parents, return null.
        if (query == null) {
            DatabaseQuery parentQuery =  getQueryFromParent(name, arguments);
            if (parentQuery != null && parentQuery.isReadQuery()) {
                parentQuery = (DatabaseQuery) parentQuery.clone();
                ((ObjectLevelReadQuery)parentQuery).setReferenceClass(getDescriptor().getJavaClass());
                addQuery(name, parentQuery);
            }
            return parentQuery;
        }
        return query;
    
protected DatabaseQuerygetQueryFromParent(java.lang.String name, java.util.Vector arguments)
INTERNAL: CR#3711: Check if the class for this descriptor has a parent class. Then search this parent's descriptor for a query with the same name and arguments. If nothing found, return null. This method should only be used recursively by getQuery().

        ClassDescriptor descriptor = getDescriptor();
        if (descriptor.hasInheritance()) {
            InheritancePolicy inheritancePolicy = descriptor.getInheritancePolicy();
            ClassDescriptor parent = inheritancePolicy.getParentDescriptor();

            // if parent exists, check for the query
            if (parent != null) {
                return parent.getQueryManager().getQuery(name, arguments);
            }
        }
        return null;
    
public CallgetReadAllCall()
ADVANCED: Return the receiver's read-all call. This allows the user to override the read-all operation.

        if (getReadAllQuery() == null) {
            return null;
        }
        return getReadAllQuery().getDatasourceCall();
    
public ReadAllQuerygetReadAllQuery()
ADVANCED: Return the receiver's read query. This should be an instance of a valid subclass of ReadAllQuery.

        return readAllQuery;
    
public java.lang.StringgetReadAllSQLString()
ADVANCED: Return the receiver's read SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the read arguments row, through replacing the field names marked by '#' with the values for those fields. Note that this is only used on readAllObjects(Class), and not when an expression is provided.

Example, "select * from EMPLOYEE"

        if (getReadAllQuery() == null) {
            return null;
        }

        return getReadAllQuery().getSQLString();
    
public CallgetReadObjectCall()
ADVANCED: Return the receiver's read-object call. This allows the user to override the read-object operation.

        if (getReadObjectQuery() == null) {
            return null;
        }
        return getReadObjectQuery().getDatasourceCall();
    
public ReadObjectQuerygetReadObjectQuery()
ADVANCED: Return the receiver's read query. This should be an instance of a valid subclass of ReadObjectQuery. If specified this is used by the descriptor to read itself from the database. The read arguments must be the primary key of the object only. This gives the user the ability to define exactly how to read the object from the database, or access data externel from the database or from some other framework.

        return readObjectQuery;
    
public java.lang.StringgetReadObjectSQLString()
ADVANCED: Return the receiver's read SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the read arguments row, through replacing the field names marked by '#' with the values for those fields. This must accept only the primary key of the object as arguments.

Example, "select * from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID"

        if (getReadObjectQuery() == null) {
            return null;
        }

        return getReadObjectQuery().getSQLString();
    
public java.util.MapgetTablesJoinExpressions()
INTERNAL: Used in case descriptor has additional tables: each additional table mapped to an expression joining it.

        if(tablesJoinExpressions == null) {
            tablesJoinExpressions = new HashMap();
        }
        return tablesJoinExpressions;
    
public CallgetUpdateCall()
ADVANCED: Return the receiver's update call. This allows the user to override the update operation.

        if (getUpdateQuery() == null) {
            return null;
        }
        return getUpdateQuery().getDatasourceCall();
    
public UpdateObjectQuerygetUpdateQuery()
ADVANCED: Return the receiver's update query. This should be an instance of a valid subclass of UpdateObjectQuery. If specified this is used by the descriptor to insert itself into the database. If the receiver uses optimisitic locking this must raise an error on optimisitic lock failure. This gives the user the ability to define exactly how to update the data into the database, or access data externel from the database or from some other framework.

        return updateQuery;
    
public java.lang.StringgetUpdateSQLString()
ADVANCED: Return the receiver's update SQL string. This allows the user to override the SQL generated by TopLink, with there own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields. This must check the optimistic lock field and raise an error on optimistic lock failure.

Example, "update EMPLOYEE set F_NAME to #F_NAME, L_NAME to #L_NAME where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (getUpdateQuery() == null) {
            return null;
        }

        return getUpdateQuery().getSQLString();
    
public booleanhasCustomMultipleTableJoinExpression()
INTERNAL: Return if a cutsom join expression is used.

        return hasCustomMultipleTableJoinExpression;
    
public booleanhasDeleteQuery()
INTERNAL: Flag that specifies if a delete query is available

        return (deleteQuery != null);
    
public booleanhasDoesExistQuery()
INTERNAL: Flag that specifies if a does exist query is available

        return (doesExistQuery != null);
    
public booleanhasInsertQuery()
INTERNAL: Flag that specifies if a insert query is available

        return (insertQuery != null);
    
public booleanhasReadAllQuery()
INTERNAL: Flag that specifies if a read all query is available

        return (readAllQuery != null);
    
public booleanhasReadObjectQuery()
INTERNAL: Flag that specifies if a read object query is available

        return (readObjectQuery != null);
    
public booleanhasUpdateQuery()
INTERNAL: Flag that specifies if a update query is available

        return (updateQuery != null);
    
public voidinitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Post initialize the mappings


        if (getDescriptor().isAggregateDescriptor()) {
            return;
        }

        if (getMultipleTableJoinExpression() != null) {
            // Combine new multiple table expression to additional join expression
            setAdditionalJoinExpression(getMultipleTableJoinExpression().and(getAdditionalJoinExpression()));
        }

        if (getDescriptor().isAggregateCollectionDescriptor()) {
            return;
        }

        //PERF: set read-object query to cache generated SQL.
        if (!hasReadObjectQuery()) {
            // Prepare static read object query always.
            ReadObjectQuery readObjectQuery = new ReadObjectQuery();
            readObjectQuery.setSelectionCriteria(getDescriptor().getObjectBuilder().getPrimaryKeyExpression());
            setReadObjectQuery(readObjectQuery);
        }
        
        if (!hasInsertQuery()) {
            // Prepare insert query always.
            setInsertQuery(new InsertObjectQuery());
        }
        getInsertQuery().setModifyRow(getDescriptor().getObjectBuilder().buildTemplateInsertRow(session));

        if (!hasDeleteQuery()) {
            // Prepare delete query always.
            setDeleteQuery(new DeleteObjectQuery());
        }
        getDeleteQuery().setModifyRow(new DatabaseRecord());

        if (hasUpdateQuery()) {
            // Do not prepare to update by default to allow minimal update.
            getUpdateQuery().setModifyRow(getDescriptor().getObjectBuilder().buildTemplateUpdateRow(session));
        }
    
private voidpopulateQueries()
INTERNAL: populate the queries with the descriptor.


        /* CR2260
         * Descriptiron:
         *   NullPointerException accessing null descriptor
         * Fix:
         *   Initialize queries with an instantiated descriptor at this point
         */
        if (getInsertQuery() != null) {
            getInsertQuery().setDescriptor(descriptor);
        }
        if (getUpdateQuery() != null) {
            getUpdateQuery().setDescriptor(descriptor);
        }
        if (getReadObjectQuery() != null) {
            getReadObjectQuery().setReferenceClass(getDescriptor().getJavaClass());
            getReadObjectQuery().setDescriptor(descriptor);
        }
        if (getDeleteQuery() != null) {
            getDeleteQuery().setDescriptor(descriptor);
        }
        if (getReadAllQuery() != null) {
            getReadAllQuery().setReferenceClass(getDescriptor().getJavaClass());
            getReadAllQuery().setDescriptor(descriptor);
        }
        for (Iterator it = getAllQueries().iterator(); it.hasNext();) {
            ((DatabaseQuery)it.next()).setDescriptor(descriptor);
        }
    
public voidpostDelete(WriteObjectQuery query)
INTERNAL: Execute the post delete operation for the query

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).postDelete(query);
        }
    
public voidpostInsert(WriteObjectQuery query)
INTERNAL: Execute the post insert operation for the query

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).postInsert(query);
        }
    
public voidpostUpdate(WriteObjectQuery query)
INTERNAL: Execute the post update operation for the query

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).postUpdate(query);
        }
    
public voidpreDelete(WriteObjectQuery query)
INTERNAL: Execute the pre delete operation for the query

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).preDelete(query);
        }
    
public voidpreInitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialize the query manager. Any custom queries must be inherited from the parent before any initialization.

        if (getDescriptor().isAggregateDescriptor()) {
            return;
        }

        // Must inherit parent query customization if not redefined.
        if (getDescriptor().isChildDescriptor()) {
            DescriptorQueryManager parentQueryManager = getDescriptor().getInheritancePolicy().getParentDescriptor().getQueryManager();

            if ((!hasInsertQuery()) && (parentQueryManager.hasInsertQuery())) {
                setInsertQuery((InsertObjectQuery)parentQueryManager.getInsertQuery().clone());
            }
            if ((!hasUpdateQuery()) && (parentQueryManager.hasUpdateQuery())) {
                setUpdateQuery((UpdateObjectQuery)parentQueryManager.getUpdateQuery().clone());
            }
            if ((!hasDeleteQuery()) && (parentQueryManager.hasDeleteQuery())) {
                setDeleteQuery((DeleteObjectQuery)parentQueryManager.getDeleteQuery().clone());
            }
            if ((!hasReadObjectQuery()) && (parentQueryManager.hasReadObjectQuery())) {
                setReadObjectQuery((ReadObjectQuery)parentQueryManager.getReadObjectQuery().clone());
            }
            if ((!hasReadAllQuery()) && (parentQueryManager.hasReadAllQuery())) {
                setReadAllQuery((ReadAllQuery)parentQueryManager.getReadAllQuery().clone());
            }
            if ((!getDoesExistQuery().isUserDefined()) && getDoesExistQuery().shouldCheckCacheForDoesExist()) {
                setDoesExistQuery(((DoesExistQuery)parentQueryManager.getDoesExistQuery().clone()));
            }
        }
    
public voidpreInsert(WriteObjectQuery query)
INTERNAL: Execute the pre insert operation for the query.

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).preInsert(query);
        }
    
public voidpreUpdate(WriteObjectQuery query)
INTERNAL: Execute the pre update operation for the query

        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        Vector mappings = getDescriptor().getMappings();
        for (int index = 0; index < mappings.size(); index++) {
            ((DatabaseMapping)mappings.get(index)).preUpdate(query);
        }
    
public voidremoveQuery(java.lang.String queryName)
PUBLIC: Remove all queries with the given query name from the set of pre-defined queries

see
#removeQuery(String, Vector)

        queries.remove(queryName);
    
public voidremoveQuery(java.lang.String queryName, java.util.Vector argumentTypes)
PUBLIC: Remove the specific query with the given queryName and argumentTypes.

see
#removeQuery(String)

        Vector queries = (Vector)getQueries().get(queryName);
        if (queries == null) {
            return;
        } else {
            DatabaseQuery query = null;
            for (Enumeration enumtr = queries.elements(); enumtr.hasMoreElements();) {
                query = (DatabaseQuery)enumtr.nextElement();
                if (Helper.areTypesAssignable(argumentTypes, query.getArgumentTypes())) {
                    break;
                }
            }
            if (query != null) {
                queries.remove(query);
            }
        }
    
public voidsetAdditionalJoinExpression(Expression additionalJoinExpression)
ADVANCED: Set the additional join expression. Used in conjuction with multiple tables and inheritance relationships. This can also be used if a sub-expression is always required to be appended to all queries. Such as tables that are shared based on a type field without inheritance.

        this.additionalJoinExpression = additionalJoinExpression;
    
public voidsetAllQueries(java.util.Vector vector)
INTERNAL: Set pre-defined queries for the descriptor. Converts the Vector to a hashtable

        for (Enumeration enumtr = vector.elements(); enumtr.hasMoreElements();) {
            addQuery((DatabaseQuery)enumtr.nextElement());
        }
    
public voidsetDeleteCall(Call call)
ADVANCED: Set the receiver's delete call. This allows the user to override the delete operation.

        if (call == null) {
            return;
        }
        DeleteObjectQuery query = new DeleteObjectQuery();
        query.setCall(call);
        setDeleteQuery(query);
    
public voidsetDeleteQuery(DeleteObjectQuery query)
ADVANCED: Set the receiver's delete query. This should be an instance of a valid subclas of DeleteObjectQuery. If specified this is used by the descriptor to delete itself and its private parts from the database. This gives the user the ability to define exactly how to delete the data from the database, or access data external from the database or from some other framework.

        this.deleteQuery = query;
        if (query == null) {
            return;
        }
        this.deleteQuery.setIsUserDefined(true);
        this.deleteQuery.setDescriptor(getDescriptor());

    
public voidsetDeleteSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's delete SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields.

Example, "delete from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (sqlString == null) {
            return;
        }

        DeleteObjectQuery query = new DeleteObjectQuery();
        query.setSQLString(sqlString);
        setDeleteQuery(query);
    
public voidsetDescriptor(ClassDescriptor descriptor)
INTERNAL: Set the descriptor.

        this.descriptor = descriptor;
        //Gross alert: This is for the case when we are reading from XML, and 
        //we have to compensate for no descriptor available at read time.  - JL
        populateQueries();

    
public voidsetDoesExistCall(Call call)
ADVANCED: Set the receiver's does exist call. This allows the user to override the does exist operation.

        if (call == null) {
            return;
        }
        getDoesExistQuery().setCall(call);
    
public voidsetDoesExistQuery(DoesExistQuery query)
ADVANCED: Set the receiver's does exist query. This should be an instance of a valid subclas of DoesExistQuery. If specified this is used by the descriptor to query existence of an object in the database. This gives the user the ability to define exactly how to query existence from the database, or access data external from the database or from some other framework.

        this.doesExistQuery = query;
        if (query == null) {
            return;
        }
        this.doesExistQuery.setIsUserDefined(true);
        this.doesExistQuery.setDescriptor(getDescriptor());
    
public voidsetDoesExistSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's does exist SQL string. This allows the user to override the SQL generated by TopLink, with there own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields. This must return null if the object does not exist, otherwise return a database row.

Example, "select EMPLOYEE_ID from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (sqlString == null) {
            return;
        }
        getDoesExistQuery().setSQLString(sqlString);
        getDoesExistQuery().checkDatabaseForDoesExist();
    
public voidsetExistenceCheck(java.lang.String token)
INTERNAL: This method is explicitly used by the Builder only.

        if (token.equals("Check cache")) {
            checkCacheForDoesExist();
        } else if (token.equals("Check database")) {
            checkDatabaseForDoesExist();
        } else if (token.equals("Assume existence")) {
            assumeExistenceForDoesExist();
        } else if (token.equals("Assume non-existence")) {
            assumeNonExistenceForDoesExist();
        } else {
            throw DescriptorException.setExistenceCheckingNotUnderstood(token, getDescriptor());
        }
    
protected voidsetHasCustomMultipleTableJoinExpression(boolean hasCustomMultipleTableJoinExpression)
INTENAL: Set if a cutsom join expression is used.

        this.hasCustomMultipleTableJoinExpression = hasCustomMultipleTableJoinExpression;
    
public voidsetInsertCall(Call call)
ADVANCED: Set the receiver's insert call. This allows the user to override the insert operation.

        if (call == null) {
            return;
        }
        InsertObjectQuery query = new InsertObjectQuery();
        query.setCall(call);
        setInsertQuery(query);
    
public voidsetInsertQuery(InsertObjectQuery insertQuery)
ADVANCED: Set the receiver's insert query. This should be an instance of a valid subclass of InsertObjectQuery. If specified this is used by the descriptor to insert itself into the database. This gives the user the ability to define exactly how to insert the data into the database, or access data external from the database or from some other framework.

        this.insertQuery = insertQuery;
        if (insertQuery == null) {
            return;
        }
        this.insertQuery.setIsUserDefined(true);
        this.insertQuery.setDescriptor(getDescriptor());
    
public voidsetInsertSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's insert SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields.

Example, "insert into EMPLOYEE (F_NAME, L_NAME) values (#F_NAME, #L_NAME)".

        if (sqlString == null) {
            return;
        }

        InsertObjectQuery query = new InsertObjectQuery();
        query.setSQLString(sqlString);
        setInsertQuery(query);
    
public voidsetInternalMultipleTableJoinExpression(Expression multipleTableJoinExpression)
INTERNAL: Used to set the multiple table join expression that was generated by TopLink as opposed to a custom one supplied by the user.

see
#setMultipleTableJoinExpression(Expression)

        this.multipleTableJoinExpression = multipleTableJoinExpression;
    
public voidsetMultipleTableJoinExpression(Expression multipleTableJoinExpression)
ADVANCED: This is normally generated for descriptors that have multiple tables. However, if the additional table does not reference the primary table's primary key, this expression may be set directly.

        this.multipleTableJoinExpression = multipleTableJoinExpression;
        setHasCustomMultipleTableJoinExpression(true);
    
public voidsetQueries(java.util.Map hashtable)
PUBLIC: set the pre-defined queries for the descriptor. Used to write out deployment XML

        queries = hashtable;
    
public voidsetReadAllCall(Call call)
ADVANCED: Set the receiver's read all call. This allows the user to override the read all operation. Note that this is only used on readAllObjects(Class), and not when an expression is provided.

        if (call == null) {
            return;
        }
        ReadAllQuery query = new ReadAllQuery();
        query.setCall(call);
        setReadAllQuery(query);
    
public voidsetReadAllQuery(ReadAllQuery query)
ADVANCED: Set the receiver's read all query. This should be an instance of a valid subclass of ReadAllQuery. If specified this is used by the descriptor to read all instances of its class from the database. This gives the user the ability to define exactly how to read all objects from the database, or access data external from the database or from some other framework. Note that this is only used on readAllObjects(Class), and not when an expression is provided.

        this.readAllQuery = query;
        if (query == null) {
            return;
        }

        this.readAllQuery.setIsUserDefined(true);

        /* CR2260 - Steven Vo
         * Description:
         *  NullPointerException accessing null descriptor
         * Fix:
         *   Setting query's descriptor and reference class when descriptor is not null.
         *   Otherwise, wait until the descriptor is set.See populateQueries() that is
         *   called by setDescriptor()
         */
        if (this.getDescriptor() != null) {
            this.readAllQuery.setDescriptor(getDescriptor());
            this.readAllQuery.setReferenceClassName(getDescriptor().getJavaClassName());
            try {
                readAllQuery.setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }
        }
    
public voidsetReadAllSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's read SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the read arguments row, through replacing the field names marked by '#' with the values for those fields. Note that this is only used on readAllObjects(Class), and not when an expression is provided.

Example, "select * from EMPLOYEE"

        if (sqlString == null) {
            return;
        }

        ReadAllQuery query = new ReadAllQuery();
        query.setSQLString(sqlString);
        setReadAllQuery(query);
    
public voidsetReadObjectCall(Call call)
ADVANCED: Set the receiver's read object call. This allows the user to override the read object operation. This must accept only the primary key of the object as arguments.

        if (call == null) {
            return;
        }
        ReadObjectQuery query = new ReadObjectQuery();
        query.setCall(call);
        setReadObjectQuery(query);
    
public voidsetReadObjectQuery(ReadObjectQuery query)
ADVANCED: Set the receiver's read query. This should be an instance of a valid subclass of ReadObjectQuery> If specified this is used by the descriptor to read itself from the database. The read arguments must be the primary key of the object only. This gives the user the ability to define exactly how to read the object from the database, or access data external from the database or from some other framework.

        this.readObjectQuery = query;
        if (query == null) {
            return;
        }
        this.readObjectQuery.setIsUserDefined(true);

        /* CR2260 - Steven Vo
         * Description:
         *  NullPointerException accessing null descriptor
         * Fix:
         *   Setting query's descriptor and reference class when descriptor is not null.
         *   Otherwise, wait until the descriptor is set.See populateQueries() that is
         *   called by setDescriptor()
         */
        if (this.getDescriptor() != null) {
            this.readObjectQuery.setDescriptor(getDescriptor());
            this.readObjectQuery.setReferenceClassName(getDescriptor().getJavaClassName());
            try {
                readObjectQuery.setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }
        }
    
public voidsetReadObjectSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's read SQL string. This allows the user to override the SQL generated by TopLink, with their own SQL or procedure call. The arguments are translated from the fields of the read arguments row, through replacing the field names marked by '#' with the values for those fields. This must accept only the primary key of the object as arguments.

Example, "select * from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID"

        if (sqlString == null) {
            return;
        }

        ReadObjectQuery query = new ReadObjectQuery();
        query.setSQLString(sqlString);
        setReadObjectQuery(query);
    
public voidsetUpdateCall(Call call)
ADVANCED: Set the receiver's update call. This allows the user to override the update operation.

        if (call == null) {
            return;
        }
        UpdateObjectQuery query = new UpdateObjectQuery();
        query.setCall(call);
        setUpdateQuery(query);
    
public voidsetUpdateQuery(UpdateObjectQuery updateQuery)
ADVANCED: Set the receiver's update query. This should be an instance of a valid subclass of UpdateObjectQuery. If specified this is used by the descriptor to update itself in the database. If the receiver uses optimisitic locking this must raise an error on optimisitic lock failure. This gives the user the ability to define exactly how to update the data into the database, or access data external from the database or from some other framework.

        this.updateQuery = updateQuery;
        if (updateQuery == null) {
            return;
        }
        this.updateQuery.setIsUserDefined(true);
        this.updateQuery.setDescriptor(getDescriptor());
    
public voidsetUpdateSQLString(java.lang.String sqlString)
ADVANCED: Set the receiver's update SQL string. This allows the user to override the SQL generated by TopLink, with there own SQL or procedure call. The arguments are translated from the fields of the source row, through replacing the field names marked by '#' with the values for those fields. This must check the optimistic lock field and raise an error on optimistic lock failure.

Example, "update EMPLOYEE set F_NAME to #F_NAME, L_NAME to #L_NAME where EMPLOYEE_ID = #EMPLOYEE_ID".

        if (sqlString == null) {
            return;
        }

        UpdateObjectQuery query = new UpdateObjectQuery();
        query.setSQLString(sqlString);
        setUpdateQuery(query);