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