KickJava   Java API By Example, From Geeks To Geeks.

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


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, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.queryframework;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 import oracle.toplink.essentials.exceptions.DatabaseException;
28 import oracle.toplink.essentials.exceptions.QueryException;
29 import oracle.toplink.essentials.expressions.Expression;
30 import oracle.toplink.essentials.descriptors.ClassDescriptor;
31 import oracle.toplink.essentials.expressions.ExpressionBuilder;
32
33 /**
34  * PUBLIC:
35  * A Query Class used to perform a bulk update using TopLink's expression framework.
36  * This class is provided to help optimize performance. It can be used in place
37  * of reading in all the objects to be changed and issuing single updates per
38  * instance. With this approach a single SQL UPDATE statement can be issued and
39  * then, based on the Expression provided, any objects in the cache that are
40  * effected by the update can be invalidated.
41  * <p>
42  * Notes: <ul>
43  * <li>By default, if a UOW is being used, this query will be deferred until the UOW commits.
44  * <li>UpdateAllQuery does not support foreign key updates
45  * unless the relationship is 1-1 (without back pointers.)</ul>
46  * <p>
47  * <b>Example of Usage:</b> Adding an area code. <br>
48  * <code>
49  * UpdateAllQuery updateQuery = new UpdateAllQuery(Employee.class); <br>
50  * updateQuery.setSelectionCriteria(eb.get("areaCode").isNull()); <br>
51  * updateQuery.addUpdate(eb.get("areaCode"), "613"); <br>
52  * </code>
53  *
54  * @author Guy Pelletier
55  * @date March 1, 2004
56  */

57 public class UpdateAllQuery extends ModifyAllQuery {
58
59     protected HashMap JavaDoc m_updateClauses;
60     
61     /**
62      * PUBLIC:
63      * Constructs a default update all query.
64      */

65     public UpdateAllQuery() {
66         super();
67     }
68
69     /**
70      * PUBLIC:
71      * Constructs an update all query for the Class type specified.
72      * @param referenceClass Class
73      */

74     public UpdateAllQuery(Class JavaDoc referenceClass) {
75         super(referenceClass);
76     }
77
78     /**
79      * PUBLIC:
80      * Constructs an update all query for the specified Class type and selection criteria.
81      * @param referenceClass Class type to be considered
82      * @param selectionCriteria Expression
83      */

84     public UpdateAllQuery(Class JavaDoc referenceClass, Expression selectionCriteria) {
85         super(referenceClass, selectionCriteria);
86     }
87
88     /**
89      * PUBLIC:
90      * Constructs an update all query for the Class type specified and the given
91      * ExpressionBuilder. This sets the default builder which is used for all associated
92      * expressions in the query.<br>
93      * @param referenceClass Class type to be considered
94      * @param builder ExpressionBuilder
95      */

96     public UpdateAllQuery(Class JavaDoc referenceClass, ExpressionBuilder expressionBuilder) {
97         super(referenceClass);
98         this.defaultBuilder = expressionBuilder;
99     }
100
101     /**
102      * PUBLIC:
103      * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
104      * @param field Expression Object level representation of a database query 'where' clause
105      * @param value Object, the new value
106      */

107     public void addUpdate(Expression field, Object JavaDoc value) {
108         addUpdateInternal(field, value);
109     }
110
111     /**
112      * PUBLIC:
113      * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
114      * @param attributeName String, the name of the attribute
115      * @param value Object, the new value
116      */

117     public void addUpdate(String JavaDoc attributeName, Object JavaDoc value) {
118         addUpdateInternal(attributeName, value);
119     }
120
121     /**
122      * PUBLIC:
123      * Adds the update (SET) clause to the query. This method ensures that
124      * the builder has the session and reference class set for both given Expressions.
125      * Uses default ExpressionBuilder.
126      * @param field Expression, representation of a database query 'where' clause that describes the field
127      * @param value Expression, representation of a database query 'where' clause that describes the new value
128      */

129     public void addUpdate(Expression field, Expression value) {
130         addUpdateInternal(field, value);
131     }
132
133     /**
134      * PUBLIC:
135      * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
136      * @param attributeName String, the name of the attribute
137      * @param value Expression, the new value
138      */

139     public void addUpdate(String JavaDoc attributeName, Expression value) {
140         addUpdateInternal(attributeName, value);
141     }
142     
143     /**
144      * INTERNAL:
145      */

146     protected void addUpdateInternal(Object JavaDoc fieldObject, Object JavaDoc valueObject) {
147         if(fieldObject == null) {
148             throw QueryException.updateAllQueryAddUpdateFieldIsNull(this);
149         }
150         if(m_updateClauses == null) {
151             m_updateClauses = new HashMap JavaDoc();
152         }
153         m_updateClauses.put(fieldObject, valueObject);
154     }
155
156     /**
157      * INTERNAL:
158      * Issue the SQL to the database and then merge into the cache.
159      * If we are within a UoW, the merge to the cache must not be done until
160      * the UoW merges into the parent. The UoW will trigger the merge to occur
161      * at the correct time and will ensure the cache setting is set to none at
162      * that time.
163      */

164     public Object JavaDoc executeDatabaseQuery() throws DatabaseException {
165         result = getQueryMechanism().updateAll();// fire the SQL to the database
166
mergeChangesIntoSharedCache();
167         return result;
168     }
169
170     /**
171      * INTERNAL:
172      * Return the updates stored for an update all query
173      */

174     public HashMap JavaDoc getUpdateClauses() {
175         return m_updateClauses;
176     }
177
178     /**
179      * INTERNAL:
180      * Return true if this is an update all query.
181      */

182     public boolean isUpdateAllQuery() {
183         return true;
184     }
185
186     /**
187      * INTERNAL:
188      */

189     protected void prepare() throws QueryException {
190         super.prepare();// will tell the query mechanism to prepare itself as well.
191

192         Class JavaDoc referenceClass = getReferenceClass();
193
194         // Check the reference class, must be set
195
if (referenceClass == null) {
196             throw QueryException.referenceClassMissing(this);
197         }
198
199         // Check the descriptor is set, if not try to get it from the session
200
if (getDescriptor() == null) {
201             ClassDescriptor desc = getSession().getDescriptor(referenceClass);
202
203             if (desc == null) {
204                 throw QueryException.descriptorIsMissing(referenceClass, this);
205             }
206
207             setDescriptor(desc);
208         }
209
210         ClassDescriptor descriptor = getDescriptor();
211
212         // Check the descriptor for an aggregate
213
if (descriptor.isAggregateDescriptor()) {
214             throw QueryException.aggregateObjectCannotBeDeletedOrWritten(descriptor, this);
215         }
216
217         // Check that the update statement is set. That is the bare minimum,
218
// the user can execute this query without a selection criteria though.
219
if ((getUpdateClauses() == null || getUpdateClauses().isEmpty()) && isExpressionQuery()) {
220             throw QueryException.updateStatementsNotSpecified();
221         }
222         
223         getQueryMechanism().prepareUpdateAll();
224     }
225
226     /**
227      * INTERNAL:
228      * Initialize the expression builder which should be used for this query. If
229      * there is a where clause, use its expression builder.
230      * If after this method defaultBuilder is still null,
231      * then initializeDefaultBuilder method will generate and cache it.
232      */

233     protected void initializeQuerySpecificDefaultBuilder() {
234         super.initializeQuerySpecificDefaultBuilder();
235         if(this.defaultBuilder == null && m_updateClauses != null) {
236             Iterator JavaDoc it = m_updateClauses.values().iterator();
237             while(it.hasNext() ) {
238                 Object JavaDoc value = it.next();
239                 if(value != null) {
240                     if(value instanceof Expression) {
241                         Expression valueExpression = (Expression)value;
242                         this.defaultBuilder = valueExpression.getBuilder();
243                         if(this.defaultBuilder != null) {
244                             return;
245                         }
246                     }
247                 }
248             }
249             it = m_updateClauses.keySet().iterator();
250             while(it.hasNext() ) {
251                 Object JavaDoc field = it.next();
252                 if(field instanceof Expression) {
253                     Expression fieldExpression = (Expression)field;
254                     this.defaultBuilder = fieldExpression.getBuilder();
255                     if(this.defaultBuilder != null) {
256                         return;
257                     }
258                 }
259             }
260         }
261     }
262     
263 }
Popular Tags