KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > base > EJBQueryImpl


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.internal.ejb.cmp3.base;
23
24 import java.util.*;
25 import oracle.toplink.essentials.ejb.cmp3.EJBQuery;
26 import oracle.toplink.essentials.exceptions.*;
27 import oracle.toplink.essentials.internal.helper.ClassConstants;
28 import oracle.toplink.essentials.internal.helper.Helper;
29 import oracle.toplink.essentials.internal.helper.BasicTypeHelperImpl;
30 import oracle.toplink.essentials.queryframework.*;
31 import oracle.toplink.essentials.sessions.Session;
32 import oracle.toplink.essentials.internal.parsing.EJBQLParseTree;
33 import oracle.toplink.essentials.internal.parsing.ejbql.*;
34 import oracle.toplink.essentials.internal.localization.ExceptionLocalization;
35 import oracle.toplink.essentials.sessions.DatabaseRecord;
36
37 /**
38 * Concrete EJB 3.0 query class
39 *
40 * To do:
41 * Internationalize exceptions
42 * Change TopLink exceptions to exception types used by the spec
43 * Named Parameters
44 * Report Query
45 * firstResultIndex set in query framework
46 * temporal type parameters
47 * Change single result to use ReadObjectQuery
48 **/

49 public abstract class EJBQueryImpl {
50     protected DatabaseQuery databaseQuery = null;
51     protected EntityManagerImpl entityManager = null;
52     protected String JavaDoc queryName = null;
53     protected Map parameters = null;
54     protected int firstResultIndex = -1; // -1 indicates undefined
55
protected int maxResults = -1; // -1 indicates undefined
56
protected int maxRows = -1; // -1 indicates undefined
57

58     abstract protected void throwNoResultException(String JavaDoc message);
59     abstract protected void throwNonUniqueResultException(String JavaDoc message);
60
61     /**
62      * Base constructor for EJBQueryImpl. Initializes basic variables.
63      */

64     protected EJBQueryImpl(EntityManagerImpl entityManager) {
65         parameters = new HashMap();
66         this.entityManager = entityManager;
67     }
68
69     /**
70      * Create an EJBQueryImpl with a TopLink query.
71      * @param query
72      */

73     public EJBQueryImpl(DatabaseQuery query, EntityManagerImpl entityManager) {
74         this(entityManager);
75         this.databaseQuery = query;
76     }
77
78     /**
79      * Build an EJBQueryImpl based on the given ejbql string
80      * @param ejbql
81      * @param entityManager
82      */

83     public EJBQueryImpl(String JavaDoc ejbql, EntityManagerImpl entityManager) {
84         this(ejbql, entityManager, false);
85     }
86
87     /**
88      * Create an EJBQueryImpl with either a query name or an ejbql string
89      * @param queryDescription
90      * @param entityManager
91      * @param isNamedQuery determines whether to treat the query description as ejbql or a query name
92      */

93     public EJBQueryImpl(String JavaDoc queryDescription, EntityManagerImpl entityManager, boolean isNamedQuery) {
94         this(entityManager);
95         if (isNamedQuery) {
96             this.queryName = queryDescription;
97         } else {
98             if (databaseQuery == null) {
99                 databaseQuery = buildEJBQLDatabaseQuery(queryDescription, getActiveSession());
100             }
101         }
102     }
103
104     /**
105      * Internal method to change the wrapped query to a DataModifyQuery if neccessary
106      */

107     protected void setAsSQLModifyQuery(){
108         if (getDatabaseQuery().isDataReadQuery()){
109             DataModifyQuery query = new DataModifyQuery();
110             query.setSQLString(databaseQuery.getSQLString());
111             query.setIsUserDefined(databaseQuery.isUserDefined());
112             query.setFlushOnExecute(databaseQuery.getFlushOnExecute());
113             databaseQuery = query;
114         }
115     }
116
117     /**
118      * Internal method to change the wrapped query to a DataReadQuery if neccessary
119      */

120     protected void setAsSQLReadQuery(){
121         if(getDatabaseQuery().isDataModifyQuery()){
122             DataReadQuery query = new DataReadQuery();
123             query.setUseAbstractRecord(false);
124             query.setSQLString(databaseQuery.getSQLString());
125             query.setIsUserDefined(databaseQuery.isUserDefined());
126             query.setFlushOnExecute(databaseQuery.getFlushOnExecute());
127             databaseQuery = query;
128         }
129     }
130
131     /**
132      * Build a DatabaseQuery from an EJBQL string.
133      * @param ejbql
134      * @param session the session to get the descriptors for this query for.
135      * @return a DatabaseQuery representing the given ejbql
136      */

137     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Session session) {
138         return buildEJBQLDatabaseQuery(ejbql, null, session);
139     }
140     
141     /**
142      * Build a DatabaseQuery from an EJBQL string.
143      *
144      * @param ejbql
145      * @param session the session to get the descriptors for this query for.
146      * @param hints a list of hints to be applied to the query
147      * @return a DatabaseQuery representing the given ejbql
148      */

149     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Session session, HashMap hints) {
150         return buildEJBQLDatabaseQuery(ejbql, null, session, hints, null);
151     }
152     
153     /**
154      * Build a DatabaseQuery from an EJBQL string.
155      *
156      * @param ejbql
157      * @param session the session to get the descriptors for this query for.
158      * @param hints a list of hints to be applied to the query
159      * @param classLoader the class loader to build the query with
160      * @return a DatabaseQuery representing the given ejbql
161      */

162     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Session session, HashMap hints, ClassLoader JavaDoc classLoader) {
163         return buildEJBQLDatabaseQuery(ejbql, null, session, hints, classLoader);
164     }
165     
166     /**
167      * Build a DatabaseQuery from an EJBQL string.
168      * @param ejbql
169      * @parem flushOnExecute
170      * @param session the session to get the descriptors for this query for.
171      * @return a DatabaseQuery representing the given ejbql
172      */

173     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Boolean JavaDoc flushOnExecute, Session session) {
174         return buildEJBQLDatabaseQuery(ejbql, flushOnExecute, session, null, null);
175     }
176     
177     /**
178      * Build a DatabaseQuery from an EJBQL string.
179      * @param ejbql
180      * @parem flushOnExecute
181      * @param session the session to get the descriptors for this query for.
182      * @return a DatabaseQuery representing the given ejbql
183      */

184     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Boolean JavaDoc flushOnExecute, Session session, ClassLoader JavaDoc classLoader) {
185         return buildEJBQLDatabaseQuery(ejbql, flushOnExecute, session, null, classLoader);
186     }
187     
188     /**
189      * Build a DatabaseQuery from an EJBQL string.
190      *
191      * @param ejbql
192      * @parem flushOnExecute
193      * @param session the session to get the descriptors for this query for.
194      * @param hints a list of hints to be applied to the query
195      * @return a DatabaseQuery representing the given ejbql
196      */

197     public static DatabaseQuery buildEJBQLDatabaseQuery(String JavaDoc ejbql, Boolean JavaDoc flushOnExecute, Session session, HashMap hints, ClassLoader JavaDoc classLoader) {
198         DatabaseQuery databaseQuery = null;
199         EJBQLParser parser = EJBQLParserBase.parseEJBQLString(ejbql);
200         EJBQLParseTree parseTree = (EJBQLParseTree)parser.getParseTree();
201         parseTree.setClassLoader(classLoader);
202         if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isSelectNode())) {
203             databaseQuery = new ReportQuery();
204             databaseQuery.setEJBQLString(ejbql);
205             ((ReadAllQuery)databaseQuery).conformResultsInUnitOfWork();
206         } else if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isUpdateNode())) {
207             databaseQuery = new UpdateAllQuery();
208             databaseQuery.setEJBQLString(ejbql);
209             ((UpdateAllQuery)databaseQuery).setShouldDeferExecutionInUOW(false);
210         } else if ((parseTree.getQueryNode() != null) && (parseTree.getQueryNode().isDeleteNode())) {
211             databaseQuery = new DeleteAllQuery();
212             databaseQuery.setEJBQLString(ejbql);
213             ((DeleteAllQuery)databaseQuery).setShouldDeferExecutionInUOW(false);
214         }
215         parseTree.populateQuery(databaseQuery, (oracle.toplink.essentials.internal.sessions.AbstractSession)session);
216         //Bug#4646580 Add arguments to query
217
parseTree.addParametersToQuery(databaseQuery);
218         ((EJBQLCallQueryMechanism)databaseQuery.getQueryMechanism()).getEJBQLCall().setIsParsed(true);
219         databaseQuery.setFlushOnExecute(flushOnExecute);
220         
221         // apply any query hints
222
applyHints(hints, databaseQuery);
223         
224         return databaseQuery;
225     }
226     
227     /**
228      * Build a ReadAllQuery from a class and sql string.
229      *
230      * @param resultClass
231      * @param flushOnExecute
232      * @param sqlString
233      * @return
234      */

235     public static DatabaseQuery buildSQLDatabaseQuery(Class JavaDoc resultClass, String JavaDoc sqlString) {
236         return buildSQLDatabaseQuery(resultClass, sqlString, null);
237     }
238     
239     /**
240      * Build a ReadAllQuery from a class and sql string.
241      *
242      * @param resultClass
243      * @param flushOnExecute
244      * @param sqlString
245      * @param hints a list of hints to be applied to the query
246      * @return
247      */

248     public static DatabaseQuery buildSQLDatabaseQuery(Class JavaDoc resultClass, String JavaDoc sqlString, HashMap hints) {
249         ReadAllQuery query = new ReadAllQuery(resultClass);
250         query.setSQLString(sqlString);
251         query.setIsUserDefined(true);
252         
253         // apply any query hints
254
applyHints(hints, query);
255
256         return query;
257     }
258     /**
259      * Build a ResultSetMappingQuery from a sql result set mapping name and sql string.
260      *
261      * @param sqlResultSetMappingName
262      * @param flushOnExecute
263      * @param sqlString
264      * @return
265      */

266     public static DatabaseQuery buildSQLDatabaseQuery(String JavaDoc sqlResultSetMappingName, String JavaDoc sqlString) {
267         return buildSQLDatabaseQuery(sqlResultSetMappingName, sqlString, null);
268     }
269     
270     /**
271      * Build a ResultSetMappingQuery from a sql result set mapping name and sql string.
272      *
273      * @param sqlResultSetMappingName
274      * @param flushOnExecute
275      * @param sqlString
276      * @param hints a list of hints to be applied to the query
277      * @return
278      */

279     public static DatabaseQuery buildSQLDatabaseQuery(String JavaDoc sqlResultSetMappingName, String JavaDoc sqlString, HashMap hints) {
280         ResultSetMappingQuery query = new ResultSetMappingQuery();
281         query.setSQLResultSetMappingName(sqlResultSetMappingName);
282         query.setSQLString(sqlString);
283         query.setIsUserDefined(true);
284         
285         // apply any query hints
286
applyHints(hints, query);
287
288         return query;
289     }
290
291     /**
292      * Build a DataReadQuery from a sql string.
293      */

294     public static DatabaseQuery buildSQLDatabaseQuery(String JavaDoc sqlString, Boolean JavaDoc flushOnExecute) {
295         return buildSQLDatabaseQuery(sqlString, new HashMap());
296     }
297     
298     /**
299      * Build a DataReadQuery from a sql string.
300      */

301     public static DatabaseQuery buildSQLDatabaseQuery(String JavaDoc sqlString, HashMap hints) {
302         DataReadQuery query = new DataReadQuery();
303         query.setUseAbstractRecord(false);
304         query.setSQLString(sqlString);
305         query.setIsUserDefined(true);
306
307         // apply any query hints
308
applyHints(hints, query);
309         
310         return query;
311     }
312
313     /**
314      * Execute a ReadQuery by assigning the stored parameter values and running it
315      * in the database
316      * @return the results of the query execution
317      */

318     protected Object JavaDoc executeReadQuery() {
319         Vector parameterValues = processParameters();
320         //TODO: the following performFlush() call is a temporary workaround for bug 4752493:
321
// CTS: INMEMORY QUERYING IN EJBQUERY BROKEN DUE TO CHANGE TO USE REPORTQUERY.
322
// Ideally we should only flush in case the selectionExpression can't be conformed in memory.
323
// There are two alternative ways to implement that:
324
// 1. Try running the query with conformInUOW flag first - if it fails with
325
// QueryException.cannotConformExpression then flush and run the query again -
326
// now without conforming.
327
// 2. Implement a new isComformable method on Expression which would determine whether the expression
328
// could be conformed in memory, flush only in case it returns false.
329
// Note that doesConform method currently implemented on Expression
330
// requires object(s) to be confirmed as parameter(s).
331
// The new isComformable method should not take any objects as parameters,
332
// it should return false if there could be such an object that
333
// passed to doesConform causes it to throw QueryException.cannotConformExpression -
334
// and true otherwise.
335
boolean shouldResetConformResultsInUnitOfWork = false;
336         if(isFlushModeAUTO()) {
337             performPreQueryFlush();
338             if(getDatabaseQuery().isObjectLevelReadQuery()) {
339                 if(((ObjectLevelReadQuery)getDatabaseQuery()).shouldConformResultsInUnitOfWork()) {
340                     ((ObjectLevelReadQuery)getDatabaseQuery()).setCacheUsage(ObjectLevelReadQuery.UseDescriptorSetting);
341                     shouldResetConformResultsInUnitOfWork = true;
342                 }
343             }
344         }
345         try {
346             return getActiveSession().executeQuery(getDatabaseQuery(), parameterValues);
347         } finally {
348             if(shouldResetConformResultsInUnitOfWork) {
349                 ((ObjectLevelReadQuery)getDatabaseQuery()).conformResultsInUnitOfWork();
350             }
351         }
352     }
353
354     /**
355     * Execute an update or delete statement.
356     * @return the number of entities updated or deleted
357     */

358     public int executeUpdate() {
359         //bug51411440: need to throw IllegalStateException if query executed on closed em
360
entityManager.verifyOpen();
361         setAsSQLModifyQuery();
362         //bug:4294241, only allow modify queries - UpdateAllQuery prefered
363
if ( !(getDatabaseQuery() instanceof ModifyQuery) ){
364             throw new IllegalStateException JavaDoc(ExceptionLocalization.buildMessage("incorrect_query_for_execute_update"));
365         }
366         //fix for bug:4288845, did not add the parameters to the query
367
Vector parameterValues = processParameters();
368         if(isFlushModeAUTO()) {
369             performPreQueryFlush();
370         }
371         Integer JavaDoc changedRows = (Integer JavaDoc)((Session)getActiveSession()).executeQuery(databaseQuery, parameterValues);
372         return changedRows.intValue();
373     }
374
375     /**
376      * Return the cached database query for this EJBQueryImpl. If the query is
377      * a named query and it has not yet been looked up, the query will be looked up
378      * and stored as the cached query.
379      */

380     public DatabaseQuery getDatabaseQuery() {
381         if ((queryName != null) && (databaseQuery == null)) {
382             // need error checking and appropriate exception for non-existing query
383
databaseQuery = getActiveSession().getQuery(queryName);
384             if (databaseQuery != null) {
385                 if (!databaseQuery.isPrepared()){
386                     //prepare the query before cloning, this ensures we do not have to continually prepare on each usage
387
databaseQuery.prepareCall(getActiveSession(), new DatabaseRecord());
388                 }
389                 //Bug5040609 Make a clone of the original DatabaseQuery for this EJBQuery
390
databaseQuery = (DatabaseQuery)databaseQuery.clone();
391             } else {
392                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("unable_to_find_named_query", new Object JavaDoc[] {queryName}));
393             }
394             
395         }
396         return databaseQuery;
397     }
398
399     /**
400      * Non-standard method to return results of a ReadQuery that has a containerPoliry
401      * that returns objects as a collection rather than a List
402      * @return Collection of results
403      */

404     public Collection getResultCollection() {
405         //bug51411440: need to throw IllegalStateException if query executed on closed em
406
entityManager.verifyOpen();
407         setAsSQLReadQuery();
408         propagateResultProperties();
409         //bug:4297903, check container policy class and throw exception if its not the right type
410
if (getDatabaseQuery() instanceof ReadAllQuery){
411           Class JavaDoc containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass();
412           if (! Helper.classImplementsInterface(containerClass, ClassConstants.Collection_Class)){
413             throw QueryException.invalidContainerClass( containerClass, ClassConstants.Collection_Class );
414           }
415         } else if (getDatabaseQuery() instanceof ReadObjectQuery){
416             //bug:4300879, no support for ReadObjectQuery if a collection is required
417
throw QueryException.incorrectQueryObjectFound( getDatabaseQuery(), ReadAllQuery.class );
418         } else if (!(getDatabaseQuery() instanceof ReadQuery)){
419             throw new IllegalStateException JavaDoc(ExceptionLocalization.buildMessage("incorrect_query_for_get_result_collection"));
420         }
421         Object JavaDoc result = executeReadQuery();
422         return (Collection)result;
423     }
424
425     /**
426     * Execute the query and return the query results
427     * as a List.
428     * @return a list of the results
429     */

430     public List getResultList() {
431         //bug51411440: need to throw IllegalStateException if query executed on closed em
432
entityManager.verifyOpen();
433         setAsSQLReadQuery();
434         propagateResultProperties();
435         //bug:4297903, check container policy class and throw exception if its not the right type
436
if (getDatabaseQuery() instanceof ReadAllQuery){
437           Class JavaDoc containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass();
438           if (! Helper.classImplementsInterface(containerClass, ClassConstants.List_Class)){
439             throw QueryException.invalidContainerClass( containerClass, ClassConstants.List_Class );
440           }
441         } else if (getDatabaseQuery() instanceof ReadObjectQuery){
442             //bug:4300879, handle ReadObjectQuery returning null
443
throw QueryException.incorrectQueryObjectFound( getDatabaseQuery(), ReadAllQuery.class );
444         } else if (!(getDatabaseQuery() instanceof ReadQuery)){
445             throw new IllegalStateException JavaDoc(ExceptionLocalization.buildMessage("incorrect_query_for_get_result_list"));
446         }
447         Object JavaDoc result = executeReadQuery();
448         return (List)result;
449     }
450
451     /**
452     * Execute a query that returns a single result.
453     * @return the result
454     * @throws EntityNotFoundException if there is no result
455     * @throws NonUniqueResultException if more than one result
456     */

457     public Object JavaDoc getSingleResult() {
458         //bug51411440: need to throw IllegalStateException if query executed on closed em
459
entityManager.verifyOpen();
460         setAsSQLReadQuery();
461         propagateResultProperties();
462         //bug:4301674, requires lists to be returned from ReadAllQuery objects
463
if (getDatabaseQuery() instanceof ReadAllQuery){
464           Class JavaDoc containerClass = ((ReadAllQuery)getDatabaseQuery()).getContainerPolicy().getContainerClass();
465           if (! Helper.classImplementsInterface(containerClass, ClassConstants.List_Class)){
466             throw QueryException.invalidContainerClass( containerClass, ClassConstants.List_Class );
467           }
468         } else if (!(getDatabaseQuery() instanceof ReadQuery)){
469             throw new IllegalStateException JavaDoc(ExceptionLocalization.buildMessage("incorrect_query_for_get_single_result"));
470         }
471         Object JavaDoc result = executeReadQuery();
472         if (result instanceof List){
473             List results = (List)result;
474             if (results.isEmpty()) {
475                 throwNoResultException(ExceptionLocalization.buildMessage("no_entities_retrieved_for_get_single_result", (Object JavaDoc[])null));
476             } else if (results.size() > 1) {
477                 throwNonUniqueResultException(ExceptionLocalization.buildMessage("too_many_results_for_get_single_result", (Object JavaDoc[])null));
478             }
479             return results.get(0);
480         }else{
481             if (result == null) {
482                 throwNoResultException(ExceptionLocalization.buildMessage("no_entities_retrieved_for_get_single_result", (Object JavaDoc[])null));
483             }
484             return result;
485         }
486     }
487
488     /**
489      * Internal method to add the parameters values to the query prior to execution.
490      * Returns a list of parameter values in the order the parameters are
491      * defined for the databaseQuery.
492      */

493     protected Vector processParameters() {
494         if (databaseQuery == null) {
495             getDatabaseQuery();
496         }
497         List arguments = databaseQuery.getArguments();
498         if (arguments.isEmpty()) {
499             Iterator params = parameters.keySet().iterator();
500             while (params.hasNext()) {
501                 databaseQuery.addArgument((String JavaDoc)params.next());
502             }
503             arguments = databaseQuery.getArguments();
504         }
505         // now create parameterValues in the same order as the argument list
506
Vector parameterValues = new Vector(arguments.size());
507         for (Iterator i = arguments.iterator(); i.hasNext();) {
508             String JavaDoc name = (String JavaDoc)i.next();
509             if (parameters.containsKey(name)) {
510                 parameterValues.add(parameters.get(name));
511             } else {
512                 // Error: missing actual parameter value
513
throw new IllegalStateException JavaDoc(ExceptionLocalization.buildMessage("missing_parameter_value", new Object JavaDoc[]{name}));
514             }
515         }
516         return parameterValues;
517     }
518
519     /**
520      * Replace the cached query with the given query.
521      */

522     public void setDatabaseQuery(DatabaseQuery query) {
523         databaseQuery = query;
524     }
525
526     /**
527     * Set the position of the first result to retrieve.
528     * @param start position of the first result, numbered from 0
529     */

530     protected void setFirstResultInternal(int startPosition) {
531         if (startPosition < 0) {
532             throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("negative_start_position", (Object JavaDoc[])null));
533         }
534         firstResultIndex = startPosition;
535     }
536
537     /**
538      * Set implementation-specific hints.
539      *
540      * @param hints a list of hints to be applied to the query
541      * @param query the query to apply the hints to
542      */

543     protected static void applyHints(HashMap hints, DatabaseQuery query) {
544         QueryHintsHandler.apply(hints, query);
545     }
546     
547
548     /**
549      * Spec. 3.5.2:
550      * "FlushMode.AUTO is set on the Query object, or if
551      * the flush mode setting for the persistence context is AUTO (the default)
552      * and a flush mode setting has not been specified for the Query object,
553      * the persistence provider is responsible for ensuring that all updates
554      * to the state of all entities in the persistence context which could potentially
555      * affect the result of the query are visible to the processing of the query."
556      */

557     protected boolean isFlushModeAUTO() {
558         if(getDatabaseQuery().getFlushOnExecute() != null) {
559             return getDatabaseQuery().getFlushOnExecute().booleanValue();
560         } else {
561             return entityManager.isFlushModeAUTO();
562         }
563     }
564     
565     /**
566      * Set an implementation-specific hint.
567      * If the hint name is not recognized, it is silently ignored.
568      * @param hintName
569      * @param value
570      * @throws IllegalArgumentException if the second argument is not
571      * valid for the implementation
572      */

573     protected void setHintInternal(String JavaDoc hintName, Object JavaDoc value) {
574         QueryHintsHandler.apply(hintName, value, getDatabaseQuery());
575     }
576
577     /**
578     * Set the maximum number of results to retrieve.
579     * @param maxResult
580     */

581     public void setMaxResultsInternal(int maxResult) {
582         if (maxResult < 0) {
583             throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("negative_max_result", (Object JavaDoc[])null));
584         }
585         this.maxResults = maxResult;
586     }
587
588     /** */
589     protected void propagateResultProperties() {
590         DatabaseQuery databaseQuery = getDatabaseQuery();
591         if (databaseQuery.isReadQuery()) {
592             ReadQuery readQuery = (ReadQuery)databaseQuery;
593             if (maxResults >= 0) {
594                 maxRows = maxResults + ((firstResultIndex >= 0) ? firstResultIndex : 0);
595                 readQuery.setMaxRows(maxRows);
596                 maxResults = -1;
597             }
598             if (firstResultIndex > -1) {
599                 readQuery.setFirstResult(firstResultIndex);
600                 firstResultIndex = -1;
601             }
602         }
603     }
604
605     /**
606     * Bind an argument to a named parameter.
607     * @param name the parameter name
608     * @param value
609     */

610     protected void setParameterInternal(String JavaDoc name, Object JavaDoc value) {
611         int index = getDatabaseQuery().getArguments().indexOf(name);
612         if (getDatabaseQuery().getEJBQLString() != null){ //only non native queries
613
if (index == -1){
614                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-wrong-argument-name",new Object JavaDoc[]{name, getDatabaseQuery().getEJBQLString()}));
615             }
616             if (!isValidActualParameter(value, getDatabaseQuery().getArgumentTypes().get(index))) {
617                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object JavaDoc[] {name, value.getClass(), getDatabaseQuery().getArgumentTypes().get(index), getDatabaseQuery().getEJBQLString()}));
618             }
619         }
620         parameters.put(name, value);
621     }
622
623     /**
624     * Bind an argument to a positional parameter.
625     * @param position
626     * @param value
627     */

628     protected void setParameterInternal(int position, Object JavaDoc value) {
629         String JavaDoc pos = (new Integer JavaDoc(position)).toString();
630         int index = getDatabaseQuery().getArguments().indexOf(pos);
631         if (getDatabaseQuery().getEJBQLString() != null){ //only non native queries
632
if (index == -1) {
633                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-wrong-argument-index", new Object JavaDoc[]{position, getDatabaseQuery().getEJBQLString()}));
634             }
635             if (!isValidActualParameter(value, getDatabaseQuery().getArgumentTypes().get(index))) {
636                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object JavaDoc[] {position, value.getClass(), getDatabaseQuery().getArgumentTypes().get(index), getDatabaseQuery().getEJBQLString()}));
637             }
638         }
639         parameters.put(pos, value);
640     }
641
642     protected boolean isValidActualParameter(Object JavaDoc value, Object JavaDoc parameterType) {
643         if (value == null) {
644             return true;
645         } else {
646             return BasicTypeHelperImpl.getInstance().isAssignableFrom(parameterType, value.getClass());
647         }
648     }
649
650     protected Session getActiveSession() {
651         return entityManager.getActiveSession();
652     }
653     
654     protected void performPreQueryFlush(){
655         if (this.entityManager.shouldFlushBeforeQuery()){
656             this.entityManager.flush();
657         }
658     }
659     
660 }
661
Popular Tags