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