KickJava   Java API By Example, From Geeks To Geeks.

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


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.*;
25 import oracle.toplink.essentials.exceptions.*;
26 import oracle.toplink.essentials.expressions.*;
27 import oracle.toplink.essentials.descriptors.DescriptorEvent;
28 import oracle.toplink.essentials.descriptors.DescriptorEventManager;
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 import oracle.toplink.essentials.descriptors.ClassDescriptor;
33
34 /**
35  * <p><b>Purpose</b>:
36  * Query used to delete a collection of objects
37  *
38  * <p><b>Responsibilities</b>:
39  * <ul>
40  * <li> Stores & retrieves the objects to delete.
41  * <li> Store the where clause used for the deletion.
42  * </ul>
43  *
44  * @author Yvon Lavoie
45  * @since TOPLink/Java 1.0
46  */

47 public class DeleteAllQuery extends ModifyAllQuery {
48
49     /* Vector containing objects to be deleted, these should be removed from the identity map after deletion. */
50     protected Vector objects;
51
52     /**
53      * PUBLIC:
54      */

55     public DeleteAllQuery() {
56         super();
57     }
58
59     /**
60      * PUBLIC:
61      * Create a new delete all query for the class specified.
62      */

63     public DeleteAllQuery(Class JavaDoc referenceClass) {
64         super(referenceClass);
65     }
66
67     /**
68      * PUBLIC:
69      * Create a new delete all query for the class and the selection criteria
70      * specified.
71      */

72     public DeleteAllQuery(Class JavaDoc referenceClass, Expression selectionCriteria) {
73         super(referenceClass, selectionCriteria);
74     }
75
76     /**
77      * PUBLIC:
78      * Return if this is a delete all query.
79      */

80     public boolean isDeleteAllQuery() {
81         return true;
82     }
83
84     /**
85      * INTERNAL:
86      * This method has to be broken. If commit manager is not active either
87      * an exception should be thrown (ObjectLevelModify case), or a transaction
88      * should be started early and execute on parent if remote (dataModify case).
89      * A modify query is NEVER executed on the parent, unless remote session.
90      * @param unitOfWork
91      * @param translationRow
92      * @return
93      * @throws oracle.toplink.essentials.exceptions.DatabaseException
94      * @throws oracle.toplink.essentials.exceptions.OptimisticLockException
95      */

96     public Object JavaDoc executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
97         if (getObjects() != null) {
98             if (unitOfWork.isAfterWriteChangesButBeforeCommit()) {
99                 throw ValidationException.illegalOperationForUnitOfWorkLifecycle(unitOfWork.getLifecycle(), "executeQuery(DeleteAllQuery)");
100             }
101     
102             // This must be broken, see comment.
103
if (!unitOfWork.getCommitManager().isActive()) {
104                 return unitOfWork.getParent().executeQuery(this, translationRow);
105             }
106             result = (Integer JavaDoc)super.execute(unitOfWork, translationRow);
107             return result;
108         } else {
109             return super.executeInUnitOfWork(unitOfWork, translationRow);
110         }
111     }
112
113     /**
114      * INTERNAL:
115      * Perform the work to delete a collection of objects.
116      * This skips the optimistic lock check and should not called for objects using locking.
117      * @exception DatabaseException - an error has occurred on the database.
118      * @return Integer the number of objects (rows) deleted.
119      */

120     public Object JavaDoc executeDatabaseQuery() throws DatabaseException {
121         // CR# 4286
122
if (getObjects() != null) {
123
124             if(isExpressionQuery() && getSelectionCriteria() == null) {
125                 // DeleteAllQuery has objects so it *must* have selectionCriteria, too
126
throw QueryException.deleteAllQuerySpecifiesObjectsButNotSelectionCriteria(getDescriptor(), this, getObjects().toString());
127             }
128             
129             // Optimistic lock check not required because objects are deleted individually in that case.
130
try {
131                 getSession().beginTransaction();
132     
133                 // Need to run pre-delete selector if available.
134
// PERF: Avoid events if no listeners.
135
if (getDescriptor().getEventManager().hasAnyEventListeners()) {
136                     for (Enumeration deletedObjectsEnum = getObjects().elements();
137                              deletedObjectsEnum.hasMoreElements();) {
138                         DescriptorEvent event = new DescriptorEvent(deletedObjectsEnum.nextElement());
139                         event.setEventCode(DescriptorEventManager.PreDeleteEvent);
140                         event.setSession(getSession());
141                         event.setQuery(this);
142                         getDescriptor().getEventManager().executeEvent(event);
143                     }
144                 }
145     
146                 result = getQueryMechanism().deleteAll();
147     
148                 // Need to run post-delete selector if available.
149
// PERF: Avoid events if no listeners.
150
if (getDescriptor().getEventManager().hasAnyEventListeners()) {
151                     for (Enumeration deletedObjectsEnum = getObjects().elements();
152                              deletedObjectsEnum.hasMoreElements();) {
153                         DescriptorEvent event = new DescriptorEvent(deletedObjectsEnum.nextElement());
154                         event.setEventCode(DescriptorEventManager.PostDeleteEvent);
155                         event.setSession(getSession());
156                         event.setQuery(this);
157                         getDescriptor().getEventManager().executeEvent(event);
158                     }
159                 }
160     
161                 if (shouldMaintainCache()) {
162                     // remove from the cache.
163
for (Enumeration objectsEnum = getObjects().elements();
164                              objectsEnum.hasMoreElements();) {
165                         Object JavaDoc deleted = objectsEnum.nextElement();
166                         if (getSession().isUnitOfWork()) {
167                             //BUG #2612169: Unwrap is needed
168
deleted = getDescriptor().getObjectBuilder().unwrapObject(deleted, getSession());
169                             ((UnitOfWorkImpl)getSession()).addObjectDeletedDuringCommit(deleted, getDescriptor());
170                         } else {
171                             getSession().getIdentityMapAccessor().removeFromIdentityMap(deleted);
172                         }
173                     }
174                 }
175     
176                 getSession().commitTransaction();
177     
178             } catch (RuntimeException JavaDoc exception) {
179                 getSession().rollbackTransaction();
180                 throw exception;
181             }
182         } else {
183             result = getQueryMechanism().deleteAll();// fire the SQL to the database
184
mergeChangesIntoSharedCache();
185         }
186         
187         return result;
188     }
189
190     /**
191      * INTERNAL:
192      * Delete all queries are executed specially to avoid cloning and ensure preparing.
193      */

194     public void executeDeleteAll(AbstractSession session, AbstractRecord translationRow, Vector objects) throws DatabaseException {
195         this.checkPrepare(session, translationRow);
196         DeleteAllQuery queryToExecute = (DeleteAllQuery)clone();
197
198         // Then prapared for the single execution.
199
queryToExecute.setTranslationRow(translationRow);
200         queryToExecute.setSession(session);
201         queryToExecute.setObjects(objects);
202         queryToExecute.prepareForExecution();
203         queryToExecute.executeDatabaseQuery();
204     }
205
206     /**
207      * PUBLIC:
208      * Return the objects that are to be deleted
209      */

210     public Vector getObjects() {
211         return objects;
212     }
213
214     /**
215      * INTERNAL:
216      * Prepare the receiver for execution in a session.
217      */

218     protected void prepare() throws QueryException {
219         super.prepare();
220
221         if (getReferenceClass() == null) {
222             throw QueryException.referenceClassMissing(this);
223         }
224
225         if (getDescriptor() == null) {
226             ClassDescriptor referenceDescriptor = getSession().getDescriptor(getReferenceClass());
227             if (referenceDescriptor == null) {
228                 throw QueryException.descriptorIsMissing(getReferenceClass(), this);
229             }
230             setDescriptor(referenceDescriptor);
231         }
232
233         if (getDescriptor().isAggregateDescriptor()) {
234             throw QueryException.aggregateObjectCannotBeDeletedOrWritten(getDescriptor(), this);
235         }
236
237         getQueryMechanism().prepareDeleteAll();
238     }
239
240     /**
241      * PUBLIC (REQUIRED):
242      * Set the objects to be deleted.
243      * Also REQUIRED is a selection criteria or SQL string that performs the deletion of the objects.
244      * This does not generate the SQL call from the deleted objects.
245      * #setObject() should not be called.
246      *
247      * Vector objects used as an indicator of one of two possible
248      * ways the query may behave:
249      * objects != null - the "old" functionality used by OneToMany mapping
250      * objects deleted from the cache, either selection expression or custom sql
251      * should be provided for deletion from db;
252      * objects == null - the "new" functionality (on par with UpdateAllQuery)
253      * the cache is either left alone or in-memory query finds the cached objects to be deleted,
254      * and these objects are invalidated in cache.
255      *
256      * Note that empty objects is still objects != case.
257      * Signal that no cache altering is required.
258      * Used by AggregationCollectionMapping and OneToManyMapping in case they use indirection
259      * and the ValueHolder has not been instantiated.
260      */

261     public void setObjects(Vector objectCollection) {
262         objects = objectCollection;
263     }
264 }
265
Popular Tags