KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > queryframework > ModifyAllQuery


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.queryframework;
23
24 import java.util.Vector JavaDoc;
25 import oracle.toplink.essentials.exceptions.*;
26 import oracle.toplink.essentials.expressions.*;
27 import oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism;
28 import oracle.toplink.essentials.internal.queryframework.ExpressionQueryMechanism;
29 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
30 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
31 import oracle.toplink.essentials.internal.sessions.AbstractSession;
32
33 /**
34  * PUBLIC:
35  * Query used to perform a bulk delete using TopLink's expression framework.
36  *
37  * @author Andrei Ilitchev
38  * @date August 18, 2005
39  */

40 public abstract class ModifyAllQuery extends ModifyQuery {
41
42     /** Cache usage flags */
43     public static final int NO_CACHE = 0;
44     public static final int INVALIDATE_CACHE = 1;
45
46     private int m_cacheUsage = INVALIDATE_CACHE;
47
48     protected Class JavaDoc referenceClass;
49     protected String JavaDoc referenceClassName;
50     
51     /** Number of modified objects */
52     protected transient Integer JavaDoc result;
53
54     /** Indicates whether execution should be deferred in UOW */
55     private boolean shouldDeferExecutionInUOW;
56
57     /** Provide a default builder so that it's easier to be consistent */
58     protected ExpressionBuilder defaultBuilder;
59     
60     /** Indicates whether the query was prepared so that it will execute using temp storage */
61     protected boolean isPreparedUsingTempStorage;
62     
63     /**
64      * PUBLIC:
65      */

66     public ModifyAllQuery() {
67         super();
68         shouldDeferExecutionInUOW = true;
69     }
70
71     /**
72      * PUBLIC:
73      * Create a new update all query for the class specified.
74      */

75     public ModifyAllQuery(Class JavaDoc referenceClass) {
76         this();
77         setReferenceClass(referenceClass);
78     }
79
80     /**
81      * PUBLIC:
82      * Create a new update all query for the class and the selection criteria
83      * specified.
84      */

85     public ModifyAllQuery(Class JavaDoc referenceClass, Expression selectionCriteria) {
86         this();
87         setReferenceClass(referenceClass);
88         setSelectionCriteria(selectionCriteria);
89     }
90
91     /**
92      * PUBLIC:
93      * Return true if this is a modify query.
94      */

95     public boolean isModifyQuery() {
96         return true;
97     }
98
99     /**
100      * INTERNAL:
101      */

102     public void setIsPreparedUsingTempStorage(boolean isPreparedUsingTempStorage) {
103         this.isPreparedUsingTempStorage = isPreparedUsingTempStorage;
104     }
105
106     /**
107      * INTERNAL:
108      */

109     public boolean isPreparedUsingTempStorage() {
110         return isPreparedUsingTempStorage;
111     }
112
113     /**
114      * INTERNAL
115      * Used to give the subclasses oportunity to copy aspects of the cloned query
116      * to the original query. The clones of all the ModifyAllQueries will be added to modifyAllQueries for validation.
117      */

118     protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
119         super.clonedQueryExecutionComplete(query, session);
120         
121         if (session.isUnitOfWork()) {
122             ((UnitOfWorkImpl)session).storeModifyAllQuery(query);
123         }
124     }
125
126     /**
127      * INTERNAL:
128      * Override query execution where Session is a UnitOfWork.
129      * <p>
130      * If there are objects in the cache return the results of the cache lookup.
131      *
132      * @param unitOfWork - the session in which the receiver will be executed.
133      * @param translationRow - the arguments
134      * @exception DatabaseException - an error has occurred on the database.
135      * @exception OptimisticLockException - an error has occurred using the optimistic lock feature.
136      * @return An object, the result of executing the query.
137      */

138     public Object JavaDoc executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
139         if (unitOfWork.isNestedUnitOfWork()) {
140             throw ValidationException.nestedUOWNotSupportedForModifyAllQuery();
141         }
142
143         //Bug4607551 For UpdateAllQuery, if deferred, add the original query with a translation row to the deferredUpdateAllQueries for execution.
144
//No action for non-deferred. Later on the clones of all the UpdateAllQuery's will be added to modifyAllQueries for validation.
145
if(shouldDeferExecutionInUOW()) {
146             unitOfWork.storeDeferredModifyAllQuery(this, translationRow);
147             result = null;
148         } else {
149             if(!unitOfWork.isInTransaction()) {
150                 unitOfWork.beginEarlyTransaction();
151             }
152             unitOfWork.setWasNonObjectLevelModifyQueryExecuted(true);
153             result = (Integer JavaDoc)super.executeInUnitOfWork(unitOfWork, translationRow);
154         }
155         return result;
156     }
157
158     /**
159      * PUBLIC:
160      * Return the cache usage for this query.
161      */

162     public int getCacheUsage() {
163         return m_cacheUsage;
164     }
165
166     /**
167      * PUBLIC:
168      * Get the expression builder which should be used for this query.
169      * This expression builder should be used to build all expressions used by this query.
170      */

171     public ExpressionBuilder getExpressionBuilder() {
172         if (defaultBuilder == null) {
173             initializeDefaultBuilder();
174         }
175
176         return defaultBuilder;
177     }
178     
179     /**
180      * INTERNAL
181      * Sets the default expression builder for this query.
182      */

183     public void setExpressionBuilder(ExpressionBuilder builder) {
184         this.defaultBuilder = builder;
185     }
186
187     /**
188      * INTERNAL:
189      * Return the name of the reference class of the query.
190      * Used by the Mappign Workbench to avoid classpath dependancies
191      */

192     public String JavaDoc getReferenceClassName() {
193         if ((referenceClassName == null) && (referenceClass != null)) {
194             referenceClassName = referenceClass.getName();
195         }
196         return referenceClassName;
197     }
198
199     /**
200      * PUBLIC:
201      * Return the reference class for this query.
202      */

203     public Class JavaDoc getReferenceClass() {
204         return referenceClass;
205     }
206
207     /**
208      * INTERNAL:
209      * Invalid the cache, that is, those objects in the cache that were affected
210      * by the query.
211      */

212     protected void invalidateCache() {
213         oracle.toplink.essentials.sessions.IdentityMapAccessor identityMapAccessor = getSession().getIdentityMapAccessor();
214         if (getSelectionCriteria() == null) {
215             // Invalidate the whole class since the user did not specify a where clause
216
if(getDescriptor().isChildDescriptor()) {
217                 Vector JavaDoc collectionToInvalidate = identityMapAccessor.getAllFromIdentityMap(null, getReferenceClass(), getTranslationRow(), null);
218                 identityMapAccessor.invalidateObjects(collectionToInvalidate);
219             } else {
220                 // if it's either a root class or there is no inheritance just clear the identity map
221
identityMapAccessor.invalidateClass(getReferenceClass());
222             }
223         } else {
224             // Invalidate only those objects in the cache that match the selection criteria
225
//Bug:4293920, expression parameters were not passed in
226
boolean noObjectsModifiedInDb = result != null && result.intValue() == 0;
227             try {
228                 InMemoryQueryIndirectionPolicy policy = new InMemoryQueryIndirectionPolicy();
229                 if(noObjectsModifiedInDb) {
230                     policy.ignoreIndirectionExceptionReturnNotConformed();
231                 } else {
232                     policy.ignoreIndirectionExceptionReturnConformed();
233                 }
234                 Vector JavaDoc collectionToInvalidate = identityMapAccessor.getAllFromIdentityMap(getSelectionCriteria(), getReferenceClass(), getTranslationRow(), policy);
235                 identityMapAccessor.invalidateObjects(collectionToInvalidate);
236             } catch (QueryException ex) {
237                 if(ex.getErrorCode() == QueryException.CANNOT_CONFORM_EXPRESSION) {
238                     // If no objects changed in the db - don't invalidate, ignore.
239
if(!noObjectsModifiedInDb) {
240                         // Invalidate the whole class since the expression can't be selected in memory
241
identityMapAccessor.invalidateClass(getReferenceClass());
242                     }
243                 } else {
244                     throw ex;
245                 }
246             }
247         }
248     }
249
250     /**
251      * INTERNAL:
252      * After execution we need to merge the changes into the shared cache
253      */

254     public void mergeChangesIntoSharedCache() {
255         if (shouldInvalidateCache()) {
256             invalidateCache();
257         }
258     }
259
260     /**
261      * PUBLIC:
262      * Set the level of cache support for this query, either NONE or INVALIDATE.
263      */

264     public void setCacheUsage(int cacheUsage) {
265         m_cacheUsage = cacheUsage;
266     }
267
268     /**
269      * PUBLIC:
270      * Set the reference class this query.
271      */

272     public void setReferenceClass(Class JavaDoc referenceClass) {
273         if (this.referenceClass != referenceClass) {
274             setIsPrepared(false);
275         }
276         this.referenceClass = referenceClass;
277     }
278
279     /**
280      * INTERNAL:
281      * Set the class name of the reference class of this query.
282      * Used by the Mapping Workbench to avoid classpath dependancies.
283      */

284     public void setReferenceClassName(String JavaDoc className) {
285         referenceClassName = className;
286     }
287     
288     /**
289      * PUBLIC:
290      * Set a flag indicating whether execution should be deferred in UOW until commit.
291      */

292     public void setShouldDeferExecutionInUOW(boolean shouldDeferExecutionInUOW) {
293         this.shouldDeferExecutionInUOW = shouldDeferExecutionInUOW;
294     }
295     
296     /**
297      * PUBLIC:
298      * Indicates whether execution should be deferred in UOW until commit.
299      */

300     public boolean shouldDeferExecutionInUOW() {
301         return shouldDeferExecutionInUOW;
302     }
303     
304     /**
305      * INTERNAL:
306      */

307     protected boolean shouldInvalidateCache() {
308         return m_cacheUsage == INVALIDATE_CACHE;
309     }
310
311     /**
312      * INTERNAL:
313      * Initialize the expression builder which should be used for this query. If
314      * there is a where clause, use its expression builder, otherwise
315      * generate one and cache it. This helps avoid unnecessary rebuilds.
316      */

317     protected void initializeDefaultBuilder() {
318         initializeQuerySpecificDefaultBuilder();
319         if(defaultBuilder == null) {
320             defaultBuilder = new ExpressionBuilder();
321         }
322     }
323     
324     /**
325      * INTERNAL:
326      * Initialize the expression builder which should be used for this query. If
327      * there is a where clause, use its expression builder.
328      * If after this method defaultBuilder is still null,
329      * then initializeDefaultBuilder method will generate and cache it.
330      */

331     protected void initializeQuerySpecificDefaultBuilder() {
332         DatabaseQueryMechanism mech = getQueryMechanism();
333         if (mech.isExpressionQueryMechanism() && ((ExpressionQueryMechanism)mech).getExpressionBuilder() != null) {
334             this.defaultBuilder = ((ExpressionQueryMechanism)mech).getExpressionBuilder();
335         }
336     }
337 }
338
Popular Tags