All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.toplink.essentials.queryframework.ModifyAllQuery Maven / Gradle / Ivy

There is a newer version: 2.1-60f
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
 * 
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package oracle.toplink.essentials.queryframework;

import java.util.Vector;
import oracle.toplink.essentials.exceptions.*;
import oracle.toplink.essentials.expressions.*;
import oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism;
import oracle.toplink.essentials.internal.queryframework.ExpressionQueryMechanism;
import oracle.toplink.essentials.internal.sessions.AbstractRecord;
import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
import oracle.toplink.essentials.internal.sessions.AbstractSession;

/**
 * PUBLIC:
 * Query used to perform a bulk delete using TopLink's expression framework.
 *
 * @author Andrei Ilitchev
 * @date August 18, 2005
 */
public abstract class ModifyAllQuery extends ModifyQuery {

    /** Cache usage flags */
    public static final int NO_CACHE = 0;
    public static final int INVALIDATE_CACHE = 1;

    private int m_cacheUsage = INVALIDATE_CACHE;

    protected Class referenceClass;
    protected String referenceClassName;
    
    /** Number of modified objects */
    protected transient Integer result;

    /** Indicates whether execution should be deferred in UOW */
    private boolean shouldDeferExecutionInUOW;

    /** Provide a default builder so that it's easier to be consistent */
    protected ExpressionBuilder defaultBuilder;
    
    /** Indicates whether the query was prepared so that it will execute using temp storage */
    protected boolean isPreparedUsingTempStorage;
    
    /**
     * PUBLIC:
     */
    public ModifyAllQuery() {
        super();
        shouldDeferExecutionInUOW = true;
    }

    /**
     * PUBLIC:
     * Create a new update all query for the class specified.
     */
    public ModifyAllQuery(Class referenceClass) {
        this();
        setReferenceClass(referenceClass);
    }

    /**
     * PUBLIC:
     * Create a new update all query for the class and the selection criteria
     * specified.
     */
    public ModifyAllQuery(Class referenceClass, Expression selectionCriteria) {
        this();
        setReferenceClass(referenceClass);
        setSelectionCriteria(selectionCriteria);
    }

    /**
     * PUBLIC:
     * Return true if this is a modify query.
     */
    public boolean isModifyQuery() {
        return true;
    }

    /**
     * INTERNAL:
     */
    public void setIsPreparedUsingTempStorage(boolean isPreparedUsingTempStorage) {
        this.isPreparedUsingTempStorage = isPreparedUsingTempStorage;
    }

    /**
     * INTERNAL:
     */
    public boolean isPreparedUsingTempStorage() {
        return isPreparedUsingTempStorage;
    }

    /**
     * INTERNAL
     * Used to give the subclasses oportunity to copy aspects of the cloned query
     * to the original query.  The clones of all the ModifyAllQueries will be added to modifyAllQueries for validation.
     */
    protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
        super.clonedQueryExecutionComplete(query, session);
        
        if (session.isUnitOfWork()) {
            ((UnitOfWorkImpl)session).storeModifyAllQuery(query);
        }
    }

    /**
     * INTERNAL:
     * Override query execution where Session is a UnitOfWork.
     * 

* If there are objects in the cache return the results of the cache lookup. * * @param unitOfWork - the session in which the receiver will be executed. * @param translationRow - the arguments * @exception DatabaseException - an error has occurred on the database. * @exception OptimisticLockException - an error has occurred using the optimistic lock feature. * @return An object, the result of executing the query. */ public Object executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException { if (unitOfWork.isNestedUnitOfWork()) { throw ValidationException.nestedUOWNotSupportedForModifyAllQuery(); } //Bug4607551 For UpdateAllQuery, if deferred, add the original query with a translation row to the deferredUpdateAllQueries for execution. //No action for non-deferred. Later on the clones of all the UpdateAllQuery's will be added to modifyAllQueries for validation. if(shouldDeferExecutionInUOW()) { unitOfWork.storeDeferredModifyAllQuery(this, translationRow); result = null; } else { if(!unitOfWork.isInTransaction()) { unitOfWork.beginEarlyTransaction(); } unitOfWork.setWasNonObjectLevelModifyQueryExecuted(true); result = (Integer)super.executeInUnitOfWork(unitOfWork, translationRow); } return result; } /** * PUBLIC: * Return the cache usage for this query. */ public int getCacheUsage() { return m_cacheUsage; } /** * PUBLIC: * Get the expression builder which should be used for this query. * This expression builder should be used to build all expressions used by this query. */ public ExpressionBuilder getExpressionBuilder() { if (defaultBuilder == null) { initializeDefaultBuilder(); } return defaultBuilder; } /** * INTERNAL * Sets the default expression builder for this query. */ public void setExpressionBuilder(ExpressionBuilder builder) { this.defaultBuilder = builder; } /** * INTERNAL: * Return the name of the reference class of the query. * Used by the Mappign Workbench to avoid classpath dependancies */ public String getReferenceClassName() { if ((referenceClassName == null) && (referenceClass != null)) { referenceClassName = referenceClass.getName(); } return referenceClassName; } /** * PUBLIC: * Return the reference class for this query. */ public Class getReferenceClass() { return referenceClass; } /** * INTERNAL: * Invalid the cache, that is, those objects in the cache that were affected * by the query. */ protected void invalidateCache() { oracle.toplink.essentials.sessions.IdentityMapAccessor identityMapAccessor = getSession().getIdentityMapAccessor(); if (getSelectionCriteria() == null) { // Invalidate the whole class since the user did not specify a where clause if(getDescriptor().isChildDescriptor()) { Vector collectionToInvalidate = identityMapAccessor.getAllFromIdentityMap(null, getReferenceClass(), getTranslationRow(), null); identityMapAccessor.invalidateObjects(collectionToInvalidate); } else { // if it's either a root class or there is no inheritance just clear the identity map identityMapAccessor.invalidateClass(getReferenceClass()); } } else { // Invalidate only those objects in the cache that match the selection criteria //Bug:4293920, expression parameters were not passed in boolean noObjectsModifiedInDb = result != null && result.intValue() == 0; try { InMemoryQueryIndirectionPolicy policy = new InMemoryQueryIndirectionPolicy(); if(noObjectsModifiedInDb) { policy.ignoreIndirectionExceptionReturnNotConformed(); } else { policy.ignoreIndirectionExceptionReturnConformed(); } Vector collectionToInvalidate = identityMapAccessor.getAllFromIdentityMap(getSelectionCriteria(), getReferenceClass(), getTranslationRow(), policy); identityMapAccessor.invalidateObjects(collectionToInvalidate); } catch (QueryException ex) { if(ex.getErrorCode() == QueryException.CANNOT_CONFORM_EXPRESSION) { // If no objects changed in the db - don't invalidate, ignore. if(!noObjectsModifiedInDb) { // Invalidate the whole class since the expression can't be selected in memory identityMapAccessor.invalidateClass(getReferenceClass()); } } else { throw ex; } } } } /** * INTERNAL: * After execution we need to merge the changes into the shared cache */ public void mergeChangesIntoSharedCache() { if (shouldInvalidateCache()) { invalidateCache(); } } /** * PUBLIC: * Set the level of cache support for this query, either NONE or INVALIDATE. */ public void setCacheUsage(int cacheUsage) { m_cacheUsage = cacheUsage; } /** * PUBLIC: * Set the reference class this query. */ public void setReferenceClass(Class referenceClass) { if (this.referenceClass != referenceClass) { setIsPrepared(false); } this.referenceClass = referenceClass; } /** * INTERNAL: * Set the class name of the reference class of this query. * Used by the Mapping Workbench to avoid classpath dependancies. */ public void setReferenceClassName(String className) { referenceClassName = className; } /** * PUBLIC: * Set a flag indicating whether execution should be deferred in UOW until commit. */ public void setShouldDeferExecutionInUOW(boolean shouldDeferExecutionInUOW) { this.shouldDeferExecutionInUOW = shouldDeferExecutionInUOW; } /** * PUBLIC: * Indicates whether execution should be deferred in UOW until commit. */ public boolean shouldDeferExecutionInUOW() { return shouldDeferExecutionInUOW; } /** * INTERNAL: */ protected boolean shouldInvalidateCache() { return m_cacheUsage == INVALIDATE_CACHE; } /** * INTERNAL: * Initialize the expression builder which should be used for this query. If * there is a where clause, use its expression builder, otherwise * generate one and cache it. This helps avoid unnecessary rebuilds. */ protected void initializeDefaultBuilder() { initializeQuerySpecificDefaultBuilder(); if(defaultBuilder == null) { defaultBuilder = new ExpressionBuilder(); } } /** * INTERNAL: * Initialize the expression builder which should be used for this query. If * there is a where clause, use its expression builder. * If after this method defaultBuilder is still null, * then initializeDefaultBuilder method will generate and cache it. */ protected void initializeQuerySpecificDefaultBuilder() { DatabaseQueryMechanism mech = getQueryMechanism(); if (mech.isExpressionQueryMechanism() && ((ExpressionQueryMechanism)mech).getExpressionBuilder() != null) { this.defaultBuilder = ((ExpressionQueryMechanism)mech).getExpressionBuilder(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy