001package com.avaje.ebean;
002
003import org.jetbrains.annotations.Nullable;
004
005import javax.persistence.NonUniqueResultException;
006import java.sql.Timestamp;
007import java.util.List;
008import java.util.Map;
009import java.util.Set;
010
011/**
012 * Object relational query for finding a List, Set, Map or single entity bean.
013 * <p>
014 * Example: Create the query using the API.
015 * </p>
016 * 
017 * <pre>{@code
018 *
019 * List<Order> orderList = 
020 *   ebeanServer.find(Order.class)
021 *     .fetch("customer")
022 *     .fetch("details")
023 *     .where()
024 *       .like("customer.name","rob%")
025 *       .gt("orderDate",lastWeek)
026 *     .orderBy("customer.id, id desc")
027 *     .setMaxRows(50)
028 *     .findList();
029 *   
030 * ...
031 * }</pre>
032 * 
033 * <p>
034 * Example: The same query using the query language
035 * </p>
036 * 
037 * <pre>{@code
038 *
039 * String oql = 
040 *      "  find  order "
041 *      +" fetch customer "
042 *      +" fetch details "
043 *      +" where customer.name like :custName and orderDate > :minOrderDate "
044 *      +" order by customer.id, id desc "
045 *      +" limit 50 ";
046 *   
047 * Query<Order> query = ebeanServer.createQuery(Order.class, oql);
048 * query.setParameter("custName", "Rob%");
049 * query.setParameter("minOrderDate", lastWeek);
050 *   
051 * List<Order> orderList = query.findList();
052 * ...
053 * }</pre>
054 * 
055 * <p>
056 * Example: Using a named query called "with.cust.and.details"
057 * </p>
058 * 
059 * <pre>{@code
060 *
061 * Query<Order> query = ebeanServer.createNamedQuery(Order.class,"with.cust.and.details");
062 * query.setParameter("custName", "Rob%");
063 * query.setParameter("minOrderDate", lastWeek);
064 *   
065 * List<Order> orderList = query.findList();
066 * ...
067 * }</pre>
068 * 
069 * <h3>AutoTune</h3>
070 * <p>
071 * Ebean has built in support for "AutoTune". This is a mechanism where a query
072 * can be automatically tuned based on profiling information that is collected.
073 * </p>
074 * <p>
075 * This is effectively the same as automatically using select() and fetch() to
076 * build a query that will fetch all the data required by the application and no
077 * more.
078 * </p>
079 * <p>
080 * It is expected that AutoTune will be the default approach for many queries
081 * in a system. It is possibly not as useful where the result of a query is sent
082 * to a remote client or where there is some requirement for "Read Consistency"
083 * guarantees.
084 * </p>
085 * 
086 * <h3>Query Language</h3>
087 * <p>
088 * <b>Partial Objects</b>
089 * </p>
090 * <p>
091 * The <em>find</em> and <em>fetch</em> clauses support specifying a list of
092 * properties to fetch. This results in objects that are "partially populated".
093 * If you try to get a property that was not populated a "lazy loading" query
094 * will automatically fire and load the rest of the properties of the bean (This
095 * is very similar behaviour as a reference object being "lazy loaded").
096 * </p>
097 * <p>
098 * Partial objects can be saved just like fully populated objects. If you do
099 * this you should remember to include the <em>"Version"</em> property in the
100 * initial fetch. If you do not include a version property then optimistic
101 * concurrency checking will occur but only include the fetched properties.
102 * Refer to "ALL Properties/Columns" mode of Optimistic Concurrency checking.
103 * </p>
104 * 
105 * <pre>{@code
106 * [ find  {bean type} [ ( * | {fetch properties} ) ] ]
107 * [ fetch {associated bean} [ ( * | {fetch properties} ) ] ]
108 * [ where {predicates} ]
109 * [ order by {order by properties} ]
110 * [ limit {max rows} [ offset {first row} ] ]
111 * }</pre>
112 * 
113 * <p>
114 * <b>FIND</b> <b>{bean type}</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ]
115 * </p>
116 * <p>
117 * With the find you specify the type of beans to fetch. You can optionally
118 * specify a list of properties to fetch. If you do not specify a list of
119 * properties ALL the properties for those beans are fetched.
120 * </p>
121 * <p>
122 * In object graph terms the <em>find</em> clause specifies the type of bean at
123 * the root level and the <em>fetch</em> clauses specify the paths of the object
124 * graph to populate.
125 * </p>
126 * <p>
127 * <b>FETCH</b> <b>{associated property}</b> [ ( <i>*</i> | <i>{fetch
128 * properties}</i> ) ]
129 * </p>
130 * <p>
131 * With the fetch you specify the associated property to fetch and populate. The
132 * associated property is a OneToOnem, ManyToOne, OneToMany or ManyToMany
133 * property. When the query is executed Ebean will fetch the associated data.
134 * </p>
135 * <p>
136 * For fetch of a path we can optionally specify a list of properties to fetch.
137 * If you do not specify a list of properties ALL the properties for that bean
138 * type are fetched.
139 * </p>
140 * <p>
141 * <b>WHERE</b> <b>{list of predicates}</b>
142 * </p>
143 * <p>
144 * The list of predicates which are joined by AND OR NOT ( and ). They can
145 * include named (or positioned) bind parameters. These parameters will need to
146 * be bound by {@link Query#setParameter(String, Object)}.
147 * </p>
148 * <p>
149 * <b>ORDER BY</b> <b>{order by properties}</b>
150 * </p>
151 * <p>
152 * The list of properties to order the result. You can include ASC (ascending)
153 * and DESC (descending) in the order by clause.
154 * </p>
155 * <p>
156 * <b>LIMIT</b> <b>{max rows}</b> [ OFFSET <i>{first row}</i> ]
157 * </p>
158 * <p>
159 * The limit offset specifies the max rows and first row to fetch. The offset is
160 * optional.
161 * </p>
162 * <h4>Examples of Ebean's Query Language</h4>
163 * <p>
164 * Find orders fetching all its properties
165 * </p>
166 * 
167 * <pre>{@code
168 * find order
169 * }</pre>
170 * 
171 * <p>
172 * Find orders fetching all its properties
173 * </p>
174 * 
175 * <pre>{@code
176 * find order (*)
177 * }</pre>
178 * 
179 * <p>
180 * Find orders fetching its id, shipDate and status properties. Note that the id
181 * property is always fetched even if it is not included in the list of fetch
182 * properties.
183 * </p>
184 * 
185 * <pre>{@code
186 * find order (shipDate, status)
187 * }</pre>
188 * 
189 * <p>
190 * Find orders with a named bind variable (that will need to be bound via
191 * {@link Query#setParameter(String, Object)}).
192 * </p>
193 * 
194 * <pre>{@code
195 * find order
196 * where customer.name like :custLike
197 * }</pre>
198 * 
199 * <p>
200 * Find orders and also fetch the customer with a named bind parameter. This
201 * will fetch and populate both the order and customer objects.
202 * </p>
203 * 
204 * <pre>{@code
205 * find  order
206 * fetch customer
207 * where customer.id = :custId
208 * }</pre>
209 * 
210 * <p>
211 * Find orders and also fetch the customer, customer shippingAddress, order
212 * details and related product. Note that customer and product objects will be
213 * "Partial Objects" with only some of their properties populated. The customer
214 * objects will have their id, name and shipping address populated. The product
215 * objects (associated with each order detail) will have their id, sku and name
216 * populated.
217 * </p>
218 * 
219 * <pre>{@code
220 * find  order
221 * fetch customer (name)
222 * fetch customer.shippingAddress
223 * fetch details
224 * fetch details.product (sku, name)
225 * }</pre>
226 * 
227 * <h3>Early parsing of the Query</h3>
228 * <p>
229 * When you get a Query object from a named query, the query statement has
230 * already been parsed. You can then add to that query (add fetch paths, add to
231 * the where clause) or override some of its settings (override the order by
232 * clause, first rows, max rows).
233 * </p>
234 * <p>
235 * The thought is that you can use named queries as a 'starting point' and then
236 * modify the query to suit specific needs.
237 * </p>
238 * <h3>Building the Where clause</h3>
239 * <p>
240 * You can add to the where clause using Expression objects or a simple String.
241 * Note that the ExpressionList has methods to add most of the common
242 * expressions that you will need.
243 * <ul>
244 * <li>where(String addToWhereClause)</li>
245 * <li>where().add(Expression expression)</li>
246 * <li>where().eq(propertyName, value).like(propertyName , value)...</li>
247 * </ul>
248 * </p>
249 * <p>
250 * The full WHERE clause is constructed by appending together
251 * <li>original query where clause (Named query or query.setQuery(String oql))</li>
252 * <li>clauses added via query.where(String addToWhereClause)</li>
253 * <li>clauses added by Expression objects</li>
254 * </p>
255 * <p>
256 * The above is the order that these are clauses are appended to give the full
257 * WHERE clause.
258 * </p>
259 * <h3>Design Goal</h3>
260 * <p>
261 * This query language is NOT designed to be a replacement for SQL. It is
262 * designed to be a simple way to describe the "Object Graph" you want Ebean to
263 * build for you. Each find/fetch represents a node in that "Object Graph" which
264 * makes it easy to define for each node which properties you want to fetch.
265 * </p>
266 * <p>
267 * Once you hit the limits of this language such as wanting aggregate functions
268 * (sum, average, min etc) or recursive queries etc you use SQL. Ebean's goal is
269 * to make it as easy as possible to use your own SQL to populate entity beans.
270 * Refer to {@link RawSql} .
271 * </p>
272 * 
273 * @param <T>
274 *          the type of Entity bean this query will fetch.
275 */
276public interface Query<T> {
277
278  /**
279   * Return the RawSql that was set to use for this query.
280   */
281  RawSql getRawSql();
282
283  /**
284   * Set RawSql to use for this query.
285   */
286  Query<T> setRawSql(RawSql rawSql);
287
288  /**
289   * Perform an 'As of' query using history tables to return the object graph
290   * as of a time in the past.
291   * <p>
292   *   To perform this query the DB must have underlying history tables.
293   * </p>
294   *
295   * @param asOf the date time in the past at which you want to view the data
296   */
297  Query<T> asOf(Timestamp asOf);
298
299  /**
300   * Execute the query against the draft set of tables.
301   */
302  Query<T> asDraft();
303
304  /**
305   * Execute the query including soft deleted rows.
306   */
307  Query<T> includeSoftDeletes();
308
309  /**
310   * Cancel the query execution if supported by the underlying database and
311   * driver.
312   * <p>
313   * This must be called from a different thread to the query executor.
314   * </p>
315   */
316  void cancel();
317
318  /**
319   * Return a copy of the query.
320   * <p>
321   * This is so that you can use a Query as a "prototype" for creating other
322   * query instances. You could create a Query with various where expressions
323   * and use that as a "prototype" - using this copy() method to create a new
324   * instance that you can then add other expressions then execute.
325   * </p>
326   */
327  Query<T> copy();
328
329  /**
330   * Specify the PersistenceContextScope to use for this query.
331   * <p/>
332   * When this is not set the 'default' configured on {@link com.avaje.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
333   * is used - this value defaults to {@link com.avaje.ebean.PersistenceContextScope#TRANSACTION}.
334   * <p/>
335   * Note that the same persistence Context is used for subsequent lazy loading and query join queries.
336   * <p/>
337   * Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for
338   * queries executed as #findIterate, #findEach, #findEachWhile.
339   *
340   * @param scope The scope to use for this query and subsequent lazy loading.
341   */
342  Query<T> setPersistenceContextScope(PersistenceContextScope scope);
343
344  /**
345   * Return the ExpressionFactory used by this query.
346   */
347  ExpressionFactory getExpressionFactory();
348
349  /**
350   * Returns true if this query was tuned by autoTune.
351   */
352  boolean isAutoTuned();
353
354  /**
355   * Explicitly specify whether to use AutoTune for this query.
356   * <p>
357   * If you do not call this method on a query the "Implicit AutoTune mode" is
358   * used to determine if AutoTune should be used for a given query.
359   * </p>
360   * <p>
361   * AutoTune can add additional fetch paths to the query and specify which
362   * properties are included for each path. If you have explicitly defined some
363   * fetch paths AutoTune will not remove them.
364   * </p>
365   */
366  Query<T> setAutoTune(boolean autoTune);
367
368  /**
369   * Set the default lazy loading batch size to use.
370   * <p>
371   * When lazy loading is invoked on beans loaded by this query then this sets the
372   * batch size used to load those beans.
373   *
374   * @param lazyLoadBatchSize the number of beans to lazy load in a single batch
375   */
376  Query<T> setLazyLoadBatchSize(int lazyLoadBatchSize);
377
378  /**
379   * Disable read auditing for this query.
380   * <p>
381   * This is intended to be used when the query is not a user initiated query and instead
382   * part of the internal processing in an application to load a cache or document store etc.
383   * In these cases we don't want the query to be part of read auditing.
384   * </p>
385   */
386  Query<T> setDisableReadAuditing();
387
388  /**
389   * Explicitly set a comma delimited list of the properties to fetch on the
390   * 'main' root level entity bean (aka partial object). Note that '*' means all
391   * properties.
392   * <p>
393   * You use {@link #fetch(String, String)} to specify specific properties to fetch
394   * on other non-root level paths of the object graph.
395   * </p>
396   *
397   * <pre>{@code
398   *
399   * List<Customer> customers =
400   *     ebeanServer.find(Customer.class)
401   *     // Only fetch the customer id, name and status.
402   *     // This is described as a "Partial Object"
403   *     .select("name, status")
404   *     .where.ilike("name", "rob%")
405   *     .findList();
406   *
407   * }</pre>
408   *
409   * @param fetchProperties
410   *          the properties to fetch for this bean (* = all properties).
411   */
412  Query<T> select(String fetchProperties);
413
414  /**
415   * Specify a path to <em>fetch</em> with its specific properties to include
416   * (aka partial object).
417   * <p>
418   * When you specify a join this means that property (associated bean(s)) will
419   * be fetched and populated. If you specify "*" then all the properties of the
420   * associated bean will be fetched and populated. You can specify a comma
421   * delimited list of the properties of that associated bean which means that
422   * only those properties are fetched and populated resulting in a
423   * "Partial Object" - a bean that only has some of its properties populated.
424   * </p>
425   * 
426   * <pre>{@code
427   *
428   * // query orders...
429   * List<Order> orders =
430   *     ebeanserver.find(Order.class)
431   *       // fetch the customer...
432   *       // ... getting the customers name and phone number
433   *       .fetch("customer", "name, phoneNumber")
434   * 
435   *       // ... also fetch the customers billing address (* = all properties)
436   *       .fetch("customer.billingAddress", "*")
437   *       .findList();
438   * }</pre>
439   * 
440   * <p>
441   * If columns is null or "*" then all columns/properties for that path are
442   * fetched.
443   * </p>
444   * 
445   * <pre>{@code
446   *
447   * // fetch customers (their id, name and status)
448   * List<Customer> customers =
449   *     ebeanServer.find(Customer.class)
450   *     .select("name, status")
451   *     .fetch("contacts", "firstName,lastName,email")
452   *     .findList();
453   *
454   * }</pre>
455   * 
456   * @param path
457   *          the path of an associated (1-1,1-M,M-1,M-M) bean.
458   * @param fetchProperties
459   *          properties of the associated bean that you want to include in the
460   *          fetch (* means all properties, null also means all properties).
461   */
462  Query<T> fetch(String path, String fetchProperties);
463
464  /**
465   * Additionally specify a FetchConfig to use a separate query or lazy loading
466   * to load this path.
467   *
468   * <pre>{@code
469   *
470   * // fetch customers (their id, name and status)
471   * List<Customer> customers =
472   *     ebeanServer.find(Customer.class)
473   *     .select("name, status")
474   *     .fetch("contacts", "firstName,lastName,email", new FetchConfig().lazy(10))
475   *     .findList();
476   *
477   * }</pre>
478   */
479  Query<T> fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig);
480
481  /**
482   * Specify a path to load including all its properties.
483   * <p>
484   * The same as {@link #fetch(String, String)} with the fetchProperties as "*".
485   * </p>
486   * <pre>{@code
487   *
488   * // fetch customers (their id, name and status)
489   * List<Customer> customers =
490   *     ebeanServer.find(Customer.class)
491   *     // eager fetch the contacts
492   *     .fetch("contacts")
493   *     .findList();
494   *
495   * }</pre>
496   *
497   * @param path
498   *          the property of an associated (1-1,1-M,M-1,M-M) bean.
499   */
500  Query<T> fetch(String path);
501
502  /**
503   * Additionally specify a JoinConfig to specify a "query join" and or define
504   * the lazy loading query.
505   *
506   *
507   * <pre>{@code
508   *
509   * // fetch customers (their id, name and status)
510   * List<Customer> customers =
511   *     ebeanServer.find(Customer.class)
512   *     // lazy fetch contacts with a batch size of 100
513   *     .fetch("contacts", new FetchConfig().lazy(100))
514   *     .findList();
515   *
516   * }</pre>
517   */
518  Query<T> fetch(String path, FetchConfig fetchConfig);
519
520  /**
521   * Apply the path properties replacing the select and fetch clauses.
522   * <p>
523   * This is typically used when the FetchPath is applied to both the query and the JSON output.
524   * </p>
525   */
526  Query<T> apply(FetchPath fetchPath);
527
528  /**
529   * Execute the query returning the list of Id's.
530   * <p>
531   * This query will execute against the EbeanServer that was used to create it.
532   * </p>
533   * 
534   * @see EbeanServer#findIds(Query, Transaction)
535   */
536  List<Object> findIds();
537
538  /**
539   * Execute the query iterating over the results.
540   * <p>
541   * Remember that with {@link QueryIterator} you must call
542   * {@link QueryIterator#close()} when you have finished iterating the results
543   * (typically in a finally block).
544   * </p>
545   * <p>
546   * findEach() and findEachWhile() are preferred to findIterate() as they ensure
547   * the jdbc statement and resultSet are closed at the end of the iteration.
548   * </p>
549   * <p>
550   * This query will execute against the EbeanServer that was used to create it.
551   * </p>
552   */
553  QueryIterator<T> findIterate();
554
555
556
557  /**
558   * Execute the query processing the beans one at a time.
559   * <p>
560   * This method is appropriate to process very large query results as the
561   * beans are consumed one at a time and do not need to be held in memory
562   * (unlike #findList #findSet etc)
563   * </p>
564   * <p>
565   * Note that internally Ebean can inform the JDBC driver that it is expecting larger
566   * resultSet and specifically for MySQL this hint is required to stop it's JDBC driver
567   * from buffering the entire resultSet. As such, for smaller resultSets findList() is
568   * generally preferable.
569   * </p>
570   * <p>
571   * Compared with #findEachWhile this will always process all the beans where as
572   * #findEachWhile provides a way to stop processing the query result early before
573   * all the beans have been read.
574   * </p>
575   * <p>
576   * This method is functionally equivalent to findIterate() but instead of using an
577   * iterator uses the QueryEachConsumer (SAM) interface which is better suited to use
578   * with Java8 closures.
579   * </p>
580   *
581   * <pre>{@code
582   *
583   *  ebeanServer.find(Customer.class)
584   *     .where().eq("status", Status.NEW)
585   *     .order().asc("id")
586   *     .findEach((Customer customer) -> {
587   *
588   *       // do something with customer
589   *       System.out.println("-- visit " + customer);
590   *     });
591   *
592   * }</pre>
593   *
594   * @param consumer
595   *          the consumer used to process the queried beans.
596   */
597  void findEach(QueryEachConsumer<T> consumer);
598
599  /**
600   * Execute the query using callbacks to a visitor to process the resulting
601   * beans one at a time.
602   * <p>
603   * This method is functionally equivalent to findIterate() but instead of using an
604   * iterator uses the QueryEachWhileConsumer (SAM) interface which is better suited to use
605   * with Java8 closures.
606   * </p>
607
608   *
609   * <pre>{@code
610   *
611   *  ebeanServer.find(Customer.class)
612   *     .fetch("contacts", new FetchConfig().query(2))
613   *     .where().eq("status", Status.NEW)
614   *     .order().asc("id")
615   *     .setMaxRows(2000)
616   *     .findEachWhile((Customer customer) -> {
617   *
618   *       // do something with customer
619   *       System.out.println("-- visit " + customer);
620   *
621   *       // return true to continue processing or false to stop
622   *       return (customer.getId() < 40);
623   *     });
624   *
625   * }</pre>
626   *
627   * @param consumer
628   *          the consumer used to process the queried beans.
629   */
630  void findEachWhile(QueryEachWhileConsumer<T> consumer);
631
632  /**
633   * Execute the query returning the list of objects.
634   * <p>
635   * This query will execute against the EbeanServer that was used to create it.
636   * </p>
637   *
638   * <pre>{@code
639   *
640   * List<Customer> customers =
641   *     ebeanServer.find(Customer.class)
642   *     .where().ilike("name", "rob%")
643   *     .findList();
644   *
645   * }</pre>
646   *
647   * @see EbeanServer#findList(Query, Transaction)
648   */
649  List<T> findList();
650
651  /**
652   * Execute the query returning the set of objects.
653   * <p>
654   * This query will execute against the EbeanServer that was used to create it.
655   * </p>
656   *
657   * <pre>{@code
658   *
659   * Set<Customer> customers =
660   *     ebeanServer.find(Customer.class)
661   *     .where().ilike("name", "rob%")
662   *     .findSet();
663   *
664   * }</pre>
665   *
666   * @see EbeanServer#findSet(Query, Transaction)
667   */
668  Set<T> findSet();
669
670  /**
671   * Execute the query returning a map of the objects.
672   * <p>
673   * This query will execute against the EbeanServer that was used to create it.
674   * </p>
675   * <p>
676   * You can use setMapKey() so specify the property values to be used as keys
677   * on the map. If one is not specified then the id property is used.
678   * </p>
679   * 
680   * <pre>{@code
681   *
682   * Map<?, Product> map =
683   *   ebeanServer.find(Product.class)
684   *     .setMapKey("sku")
685   *     .findMap();
686   *
687   * }</pre>
688   * 
689   * @see EbeanServer#findMap(Query, Transaction)
690   */
691  Map<?, T> findMap();
692
693  /**
694   * Return a typed map specifying the key property and type.
695   */
696  <K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
697
698  /**
699   * Execute the query returning either a single bean or null (if no matching
700   * bean is found).
701   * <p>
702   * If more than 1 row is found for this query then a NonUniqueResultException is
703   * thrown.
704   * </p>
705   * <p>
706   * This is useful when your predicates dictate that your query should only
707   * return 0 or 1 results.
708   * </p>
709   * 
710   * <pre>{@code
711   *
712   * // assuming the sku of products is unique...
713   * Product product =
714   *     ebeanServer.find(Product.class)
715   *         .where().eq("sku", "aa113")
716   *         .findUnique();
717   * ...
718   * }</pre>
719   * 
720   * <p>
721   * It is also useful with finding objects by their id when you want to specify
722   * further join information.
723   * </p>
724   * 
725   * <pre>{@code
726   *
727   * // Fetch order 1 and additionally fetch join its order details...
728   * Order order = 
729   *     ebeanServer.find(Order.class)
730   *       .setId(1)
731   *       .fetch("details")
732   *       .findUnique();
733   *
734   * // the order details were eagerly loaded
735   * List<OrderDetail> details = order.getDetails();
736   * ...
737   * }</pre>
738   *
739   * @throws NonUniqueResultException if more than one result was found
740   */
741  @Nullable
742  T findUnique();
743
744  /**
745   * Return versions of a @History entity bean.
746   * <p>
747   *   Note that this query will work against view based history implementations
748   *   but not sql2011 standards based implementations that require a start and
749   *   end timestamp to be specified.
750   * </p>
751   * <p>
752   *   Generally this query is expected to be a find by id or unique predicates query.
753   *   It will execute the query against the history returning the versions of the bean.
754   * </p>
755   */
756  List<Version<T>> findVersions();
757
758  /**
759   * Return versions of a @History entity bean between the 2 timestamps.
760   * <p>
761   *   Generally this query is expected to be a find by id or unique predicates query.
762   *   It will execute the query against the history returning the versions of the bean.
763   * </p>
764   */
765  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
766
767  /**
768   * Execute as a delete query deleting the 'root level' beans that match the predicates
769   * in the query.
770   * <p>
771   * Note that if the query includes joins then the generated delete statement may not be
772   * optimal depending on the database platform.
773   * </p>
774   *
775   * @return the number of beans/rows that were deleted.
776   */
777  int delete();
778
779  /**
780   * Return the count of entities this query should return.
781   * <p>
782   * This is the number of 'top level' or 'root level' entities.
783   * </p>
784   */
785  int findRowCount();
786
787  /**
788   * Execute find row count query in a background thread.
789   * <p>
790   * This returns a Future object which can be used to cancel, check the
791   * execution status (isDone etc) and get the value (with or without a
792   * timeout).
793   * </p>
794   * 
795   * @return a Future object for the row count query
796   */
797  FutureRowCount<T> findFutureRowCount();
798
799  /**
800   * Execute find Id's query in a background thread.
801   * <p>
802   * This returns a Future object which can be used to cancel, check the
803   * execution status (isDone etc) and get the value (with or without a
804   * timeout).
805   * </p>
806   * 
807   * @return a Future object for the list of Id's
808   */
809  FutureIds<T> findFutureIds();
810
811  /**
812   * Execute find list query in a background thread.
813   * <p>
814   * This query will execute in it's own PersistenceContext and using its own transaction.
815   * What that means is that it will not share any bean instances with other queries.
816   * </p>
817   *
818   * @return a Future object for the list result of the query
819   */
820  FutureList<T> findFutureList();
821
822  /**
823   * Return a PagedList for this query using pageIndex and pageSize.
824   * <p>
825   * The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
826   * {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
827   * {@link Query#findFutureRowCount()} to determine total row count, total page count etc.
828   * </p>
829   * <p>
830   * Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on
831   * the query. This translates into SQL that uses limit offset, rownum or row_number function to
832   * limit the result set.
833   * </p>
834   *
835   * <h4>Example: typical use including total row count</h4>
836   * <pre>{@code
837   *
838   *     // We want to find the first 100 new orders
839   *     //  ... 0 means first page
840   *     //  ... page size is 100
841   *
842   *     PagedList<Order> pagedList
843   *       = ebeanServer.find(Order.class)
844   *       .where().eq("status", Order.Status.NEW)
845   *       .order().asc("id")
846   *       .findPagedList(0, 100);
847   *
848   *     // Optional: initiate the loading of the total
849   *     // row count in a background thread
850   *     pagedList.loadRowCount();
851   *
852   *     // fetch and return the list in the foreground thread
853   *     List<Order> orders = pagedList.getList();
854   *
855   *     // get the total row count (from the future)
856   *     int totalRowCount = pagedList.getTotalRowCount();
857   *
858   * }</pre>
859   *
860   * @param pageIndex
861   *          The zero based index of the page.
862   * @param pageSize
863   *          The number of beans to return per page.
864   * @return The PagedList
865   */
866  PagedList<T> findPagedList(int pageIndex, int pageSize);
867
868  /**
869   * Return a PagedList for this query using firstRow and maxRows.
870   * <p>
871   * The benefit of using this over findList() is that it provides functionality to get the
872   * total row count etc.
873   * </p>
874   * <p>
875   * If maxRows is not set on the query prior to calling findPagedList() then a
876   * PersistenceException is thrown.
877   * </p>
878   *
879   * <pre>{@code
880   *
881   *  PagedList<Order> pagedList = Ebean.find(Order.class)
882   *       .setFirstRow(50)
883   *       .setMaxRows(20)
884   *       .findPagedList();
885   *
886   *       // fetch the total row count in the background
887   *       pagedList.loadRowCount();
888   *
889   *       List<Order> orders = pagedList.getList();
890   *       int totalRowCount = pagedList.getTotalRowCount();
891   *
892   * }</pre>
893   *
894   * @return The PagedList
895   */
896  PagedList<T> findPagedList();
897
898  /**
899   * Set a named bind parameter. Named parameters have a colon to prefix the name.
900   * 
901   * <pre>{@code
902   *
903   * // a query with a named parameter
904   * String oql = "find order where status = :orderStatus";
905   * 
906   * Query<Order> query = ebeanServer.find(Order.class, oql);
907   * 
908   * // bind the named parameter
909   * query.bind("orderStatus", OrderStatus.NEW);
910   * List<Order> list = query.findList();
911   *
912   * }</pre>
913   * 
914   * @param name
915   *          the parameter name
916   * @param value
917   *          the parameter value
918   */
919  Query<T> setParameter(String name, Object value);
920
921  /**
922   * Set an ordered bind parameter according to its position. Note that the
923   * position starts at 1 to be consistent with JDBC PreparedStatement. You need
924   * to set a parameter value for each ? you have in the query.
925   * 
926   * <pre>{@code
927   *
928   * // a query with a positioned parameter
929   * String oql = "where status = ? order by id desc";
930   * 
931   * Query<Order> query = ebeanServer.createQuery(Order.class, oql);
932   * 
933   * // bind the parameter
934   * query.setParameter(1, OrderStatus.NEW);
935   * 
936   * List<Order> list = query.findList();
937   *
938   * }</pre>
939   * 
940   * @param position
941   *          the parameter bind position starting from 1 (not 0)
942   * @param value
943   *          the parameter bind value.
944   */
945  Query<T> setParameter(int position, Object value);
946
947  /**
948   * Set the Id value to query. This is used with findUnique().
949   * <p>
950   * You can use this to have further control over the query. For example adding
951   * fetch joins.
952   * </p>
953   * 
954   * <pre>{@code
955   *
956   * Order order =
957   *     ebeanServer.find(Order.class)
958   *     .setId(1)
959   *     .fetch("details")
960   *     .findUnique();
961   *
962   * // the order details were eagerly fetched
963   * List<OrderDetail> details = order.getDetails();
964   *
965   * }</pre>
966   */
967  Query<T> setId(Object id);
968
969  /**
970   * Return the Id value.
971   */
972  Object getId();
973
974  /**
975   * Add additional clause(s) to the where clause.
976   * <p>
977   * This typically contains named parameters which will need to be set via
978   * {@link #setParameter(String, Object)}.
979   * </p>
980   * 
981   * <pre>{@code
982   *
983   * Query<Order> query = ebeanServer.createQuery(Order.class, "top");
984   * ...
985   * if (...) {
986   *   query.where("status = :status and lower(customer.name) like :custName");
987   *   query.setParameter("status", Order.NEW);
988   *   query.setParameter("custName", "rob%");
989   * }
990   *
991   * }</pre>
992   * 
993   * <p>
994   * Internally the addToWhereClause string is processed by removing named
995   * parameters (replacing them with ?) and by converting logical property names
996   * to database column names (with table alias). The rest of the string is left
997   * as is and it is completely acceptable and expected for the addToWhereClause
998   * string to include sql functions and columns.
999   * </p>
1000   * 
1001   * @param addToWhereClause
1002   *          the clause to append to the where clause which typically contains
1003   *          named parameters.
1004   * @return The query object
1005   */
1006  Query<T> where(String addToWhereClause);
1007
1008  /**
1009   * Add a single Expression to the where clause returning the query.
1010   * 
1011   * <pre>{@code
1012   *
1013   * List<Order> newOrders = 
1014   *     ebeanServer.find(Order.class)
1015   *            .where().eq("status", Order.NEW)
1016   *            .findList();
1017   * ...
1018   *
1019   * }</pre>
1020   */
1021  Query<T> where(Expression expression);
1022
1023  /**
1024   * Add Expressions to the where clause with the ability to chain on the
1025   * ExpressionList. You can use this for adding multiple expressions to the
1026   * where clause.
1027   * 
1028   * <pre>{@code
1029   *
1030   * List<Order> orders =
1031   *     ebeanServer.find(Order.class)
1032   *     .where()
1033   *       .eq("status", Order.NEW)
1034   *       .ilike("customer.name","rob%")
1035   *     .findList();
1036   *
1037   * }</pre>
1038   * 
1039   * @see Expr
1040   * @return The ExpressionList for adding expressions to.
1041   */
1042  ExpressionList<T> where();
1043
1044  /**
1045   * Add Full text search expressions for Document store queries.
1046   * <p>
1047   * This is currently ElasticSearch only and provides the full text
1048   * expressions such as Match and Multi-Match.
1049   * </p>
1050   * <p>
1051   * This automatically makes this query a "Doc Store" query and will execute
1052   * against the document store (ElasticSearch).
1053   * </p>
1054   * <p>
1055   * Expressions added here are added to the "query" section of an ElasticSearch
1056   * query rather than the "filter" section.
1057   * </p>
1058   * <p>
1059   * Expressions added to the where() are added to the "filter" section of an
1060   * ElasticSearch query.
1061   * </p>
1062   */
1063  ExpressionList<T> text();
1064
1065  /**
1066   * This applies a filter on the 'many' property list rather than the root
1067   * level objects.
1068   * <p>
1069   * Typically you will use this in a scenario where the cardinality is high on
1070   * the 'many' property you wish to join to. Say you want to fetch customers
1071   * and their associated orders... but instead of getting all the orders for
1072   * each customer you only want to get the new orders they placed since last
1073   * week. In this case you can use filterMany() to filter the orders.
1074   * </p>
1075   * 
1076   * <pre>{@code
1077   * 
1078   * List<Customer> list =
1079   *     ebeanServer.find(Customer.class)
1080   *     // .fetch("orders", new FetchConfig().lazy())
1081   *     // .fetch("orders", new FetchConfig().query())
1082   *     .fetch("orders")
1083   *     .where().ilike("name", "rob%")
1084   *     .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek)
1085   *     .findList();
1086   * 
1087   * }</pre>
1088   * 
1089   * <p>
1090   * Please note you have to be careful that you add expressions to the correct
1091   * expression list - as there is one for the 'root level' and one for each
1092   * filterMany that you have.
1093   * </p>
1094   * 
1095   * @param propertyName
1096   *          the name of the many property that you want to have a filter on.
1097   * 
1098   * @return the expression list that you add filter expressions for the many
1099   *         to.
1100   */
1101  ExpressionList<T> filterMany(String propertyName);
1102
1103  /**
1104   * Add Expressions to the Having clause return the ExpressionList.
1105   * <p>
1106   * Currently only beans based on raw sql will use the having clause.
1107   * </p>
1108   * <p>
1109   * Note that this returns the ExpressionList (so you can add multiple
1110   * expressions to the query in a fluent API way).
1111   * </p>
1112   * 
1113   * @see Expr
1114   * @return The ExpressionList for adding more expressions to.
1115   */
1116  ExpressionList<T> having();
1117
1118  /**
1119   * Add additional clause(s) to the having clause.
1120   * <p>
1121   * This typically contains named parameters which will need to be set via
1122   * {@link #setParameter(String, Object)}.
1123   * </p>
1124   * 
1125   * <pre>{@code
1126   *
1127   * List<ReportOrder> query =
1128   *     ebeanServer.find(ReportOrder.class)
1129   *     .having("score > :min").setParameter("min", 1)
1130   *     .findList();
1131   *
1132   * }</pre>
1133   * 
1134   * @param addToHavingClause
1135   *          the clause to append to the having clause which typically contains
1136   *          named parameters.
1137   * @return The query object
1138   */
1139  Query<T> having(String addToHavingClause);
1140
1141  /**
1142   * Add an expression to the having clause returning the query.
1143   * <p>
1144   * Currently only beans based on raw sql will use the having clause.
1145   * </p>
1146   * <p>
1147   * This is similar to {@link #having()} except it returns the query rather
1148   * than the ExpressionList. This is useful when you want to further specify
1149   * something on the query.
1150   * </p>
1151   * 
1152   * @param addExpressionToHaving
1153   *          the expression to add to the having clause.
1154   * @return the Query object
1155   */
1156  Query<T> having(Expression addExpressionToHaving);
1157
1158  /**
1159   * Set the order by clause replacing the existing order by clause if there is
1160   * one.
1161   * <p>
1162   * This follows SQL syntax using commas between each property with the
1163   * optional asc and desc keywords representing ascending and descending order
1164   * respectively.
1165   * </p>
1166   * <p>
1167   * This is EXACTLY the same as {@link #order(String)}.
1168   * </p>
1169   */
1170  Query<T> orderBy(String orderByClause);
1171
1172  /**
1173   * Set the order by clause replacing the existing order by clause if there is
1174   * one.
1175   * <p>
1176   * This follows SQL syntax using commas between each property with the
1177   * optional asc and desc keywords representing ascending and descending order
1178   * respectively.
1179   * </p>
1180   * <p>
1181   * This is EXACTLY the same as {@link #orderBy(String)}.
1182   * </p>
1183   */
1184  Query<T> order(String orderByClause);
1185
1186  /**
1187   * Return the OrderBy so that you can append an ascending or descending
1188   * property to the order by clause.
1189   * <p>
1190   * This will never return a null. If no order by clause exists then an 'empty'
1191   * OrderBy object is returned.
1192   * </p>
1193   * <p>
1194   * This is EXACTLY the same as {@link #orderBy()}.
1195   * </p>
1196   */
1197  OrderBy<T> order();
1198
1199  /**
1200   * Return the OrderBy so that you can append an ascending or descending
1201   * property to the order by clause.
1202   * <p>
1203   * This will never return a null. If no order by clause exists then an 'empty'
1204   * OrderBy object is returned.
1205   * </p>
1206   * <p>
1207   * This is EXACTLY the same as {@link #order()}.
1208   * </p>
1209   */
1210  OrderBy<T> orderBy();
1211
1212  /**
1213   * Set an OrderBy object to replace any existing OrderBy clause.
1214   * <p>
1215   * This is EXACTLY the same as {@link #setOrderBy(OrderBy)}.
1216   * </p>
1217   */
1218  Query<T> setOrder(OrderBy<T> orderBy);
1219
1220  /**
1221   * Set an OrderBy object to replace any existing OrderBy clause.
1222   * <p>
1223   * This is EXACTLY the same as {@link #setOrder(OrderBy)}.
1224   * </p>
1225   */
1226  Query<T> setOrderBy(OrderBy<T> orderBy);
1227
1228  /**
1229   * Set whether this query uses DISTINCT.
1230   * <p>
1231   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
1232   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
1233   * </p>
1234   * <pre>{@code
1235   *
1236   *   List<Customer> customers =
1237   *       Ebean.find(Customer.class)
1238   *          .setDistinct(true)
1239   *          .select("name")
1240   *          .findList();
1241   *
1242   * }</pre>
1243   */
1244  Query<T> setDistinct(boolean isDistinct);
1245
1246  /**
1247   * Return the first row value.
1248   */
1249  int getFirstRow();
1250
1251  /**
1252   * Set the first row to return for this query.
1253   *
1254   * @param firstRow the first row to include in the query result.
1255   */
1256  Query<T> setFirstRow(int firstRow);
1257
1258  /**
1259   * Return the max rows for this query.
1260   */
1261  int getMaxRows();
1262
1263  /**
1264   * Set the maximum number of rows to return in the query.
1265   * 
1266   * @param maxRows
1267   *          the maximum number of rows to return in the query.
1268   */
1269  Query<T> setMaxRows(int maxRows);
1270
1271  /**
1272   * Set the property to use as keys for a map.
1273   * <p>
1274   * If no property is set then the id property is used.
1275   * </p>
1276   * 
1277   * <pre>{@code
1278   *
1279   * // Assuming sku is unique for products...
1280   *    
1281   * Map<?,Product> productMap =
1282   *     ebeanServer.find(Product.class)
1283   *     // use sku for keys...
1284   *     .setMapKey("sku")
1285   *     .findMap();
1286   *
1287   * }</pre>
1288   * 
1289   * @param mapKey
1290   *          the property to use as keys for a map.
1291   */
1292  Query<T> setMapKey(String mapKey);
1293
1294  /**
1295   * Set this to true to use the bean cache.
1296   * <p>
1297   * If the query result is in cache then by default this same instance is
1298   * returned. In this sense it should be treated as a read only object graph.
1299   * </p>
1300   */
1301  Query<T> setUseCache(boolean useBeanCache);
1302
1303  /**
1304   * Set this to true to use the query cache.
1305   */
1306  Query<T> setUseQueryCache(boolean useQueryCache);
1307
1308  /**
1309   * Set to true if this query should execute against the doc store.
1310   * <p>
1311   *   When setting this you may also consider disabling lazy loading.
1312   * </p>
1313   */
1314  Query<T> setUseDocStore(boolean useDocStore);
1315
1316  /**
1317   * When set to true when you want the returned beans to be read only.
1318   */
1319  Query<T> setReadOnly(boolean readOnly);
1320
1321  /**
1322   * When set to true all the beans from this query are loaded into the bean
1323   * cache.
1324   */
1325  Query<T> setLoadBeanCache(boolean loadBeanCache);
1326
1327  /**
1328   * Set a timeout on this query.
1329   * <p>
1330   * This will typically result in a call to setQueryTimeout() on a
1331   * preparedStatement. If the timeout occurs an exception will be thrown - this
1332   * will be a SQLException wrapped up in a PersistenceException.
1333   * </p>
1334   * 
1335   * @param secs
1336   *          the query timeout limit in seconds. Zero means there is no limit.
1337   */
1338  Query<T> setTimeout(int secs);
1339
1340  /**
1341   * A hint which for JDBC translates to the Statement.fetchSize().
1342   * <p>
1343   * Gives the JDBC driver a hint as to the number of rows that should be
1344   * fetched from the database when more rows are needed for ResultSet.
1345   * </p>
1346   */
1347  Query<T> setBufferFetchSizeHint(int fetchSize);
1348
1349  /**
1350   * Return the sql that was generated for executing this query.
1351   * <p>
1352   * This is only available after the query has been executed and provided only
1353   * for informational purposes.
1354   * </p>
1355   */
1356  String getGeneratedSql();
1357
1358  /**
1359   * executed the select with "for update" which should lock the record
1360   * "on read"
1361   */
1362  Query<T> setForUpdate(boolean forUpdate);
1363
1364  /**
1365   * Return true if this query has forUpdate set.
1366   */
1367  boolean isForUpdate();
1368  
1369  /**
1370   * Set root table alias.
1371   */
1372  Query<T> alias(String alias);
1373
1374  /**
1375   * Return the type of beans being queried.
1376   */
1377  Class<T> getBeanType();
1378
1379  /**
1380   * Set true if you want to disable lazy loading.
1381   * <p>
1382   *   That is, once the object graph is returned further lazy loading is disabled.
1383   * </p>
1384   */
1385  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
1386
1387  /**
1388   * Returns the set of properties or paths that are unknown (do not map to known properties or paths).
1389   * <p>
1390   * Validate the query checking the where and orderBy expression paths to confirm if
1391   * they represent valid properties or paths for the given bean type.
1392   * </p>
1393   */
1394  Set<String> validate();
1395
1396}