001package io.ebean;
002
003import javax.annotation.Nonnull;
004import javax.annotation.Nullable;
005import javax.persistence.NonUniqueResultException;
006import java.sql.Connection;
007import java.sql.Timestamp;
008import java.util.List;
009import java.util.Map;
010import java.util.Optional;
011import java.util.Set;
012import java.util.function.Consumer;
013import java.util.function.Predicate;
014import java.util.stream.Stream;
015
016/**
017 * Object relational query for finding a List, Set, Map or single entity bean.
018 * <p>
019 * Example: Create the query using the API.
020 * </p>
021 * <p>
022 * <pre>{@code
023 *
024 * List<Order> orderList = DB.find(Order.class)
025 *     .where()
026 *       .like("customer.name","rob%")
027 *       .gt("orderDate",lastWeek)
028 *     .order("customer.id, id desc")
029 *     .setMaxRows(50)
030 *     .findList();
031 *
032 * ...
033 * }</pre>
034 * <p>
035 * Example: The same query using the query language
036 * </p>
037 * <pre>{@code
038 *
039 * String oql =
040 *      +" where customer.name like :custName and orderDate > :minOrderDate "
041 *      +" order by customer.id, id desc "
042 *      +" limit 50 ";
043 *
044 * List<Order> orderList = DB.createQuery(Order.class, oql)
045 *   .setParameter("custName", "Rob%")
046 *   .setParameter("minOrderDate", lastWeek)
047 *   .findList();
048 * ...
049 * }</pre>
050 * <h3>AutoTune</h3>
051 * <p>
052 * Ebean has built in support for "AutoTune". This is a mechanism where a query
053 * can be automatically tuned based on profiling information that is collected.
054 * </p>
055 * <p>
056 * This is effectively the same as automatically using select() and fetch() to
057 * build a query that will fetch all the data required by the application and no
058 * more.
059 * </p>
060 * <p>
061 * It is expected that AutoTune will be the default approach for many queries
062 * in a system. It is possibly not as useful where the result of a query is sent
063 * to a remote client or where there is some requirement for "Read Consistency"
064 * guarantees.
065 * </p>
066 * <h3>Query Language</h3>
067 * <p>
068 * <b>Partial Objects</b>
069 * </p>
070 * <p>
071 * The <em>find</em> and <em>fetch</em> clauses support specifying a list of
072 * properties to fetch. This results in objects that are "partially populated".
073 * If you try to get a property that was not populated a "lazy loading" query
074 * will automatically fire and load the rest of the properties of the bean (This
075 * is very similar behaviour as a reference object being "lazy loaded").
076 * </p>
077 * <p>
078 * Partial objects can be saved just like fully populated objects. If you do
079 * this you should remember to include the <em>"Version"</em> property in the
080 * initial fetch. If you do not include a version property then optimistic
081 * concurrency checking will occur but only include the fetched properties.
082 * Refer to "ALL Properties/Columns" mode of Optimistic Concurrency checking.
083 * </p>
084 * <pre>{@code
085 * [ select [ ( * | {fetch properties} ) ] ]
086 * [ fetch {path} [ ( * | {fetch properties} ) ] ]
087 * [ where {predicates} ]
088 * [ order by {order by properties} ]
089 * [ limit {max rows} [ offset {first row} ] ]
090 * }</pre>
091 * <p>
092 * <b>SELECT</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ]
093 * </p>
094 * <p>
095 * With the select you can specify a list of properties to fetch.
096 * </p>
097 * <p>
098 * <b>FETCH</b> <b>{path}</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ]
099 * </p>
100 * <p>
101 * With the fetch you specify the associated property to fetch and populate. The
102 * path is a OneToOne, ManyToOne, OneToMany or ManyToMany property.
103 * </p>
104 * <p>
105 * For fetch of a path we can optionally specify a list of properties to fetch.
106 * If you do not specify a list of properties ALL the properties for that bean
107 * type are fetched.
108 * </p>
109 * <p>
110 * <b>WHERE</b> <b>{list of predicates}</b>
111 * </p>
112 * <p>
113 * The list of predicates which are joined by AND OR NOT ( and ). They can
114 * include named (or positioned) bind parameters. These parameters will need to
115 * be bound by {@link Query#setParameter(String, Object)}.
116 * </p>
117 * <p>
118 * <b>ORDER BY</b> <b>{order by properties}</b>
119 * </p>
120 * <p>
121 * The list of properties to order the result. You can include ASC (ascending)
122 * and DESC (descending) in the order by clause.
123 * </p>
124 * <p>
125 * <b>LIMIT</b> <b>{max rows}</b> [ OFFSET <i>{first row}</i> ]
126 * </p>
127 * <p>
128 * The limit offset specifies the max rows and first row to fetch. The offset is
129 * optional.
130 * </p>
131 * <h4>Examples of Ebean's Query Language</h4>
132 * <p>
133 * Find orders fetching its id, shipDate and status properties. Note that the id
134 * property is always fetched even if it is not included in the list of fetch
135 * properties.
136 * </p>
137 * <pre>{@code
138 *
139 * select (shipDate, status)
140 *
141 * }</pre>
142 * <p>
143 * Find orders with a named bind variable (that will need to be bound via
144 * {@link Query#setParameter(String, Object)}).
145 * </p>
146 * <pre>{@code
147 *
148 * where customer.name like :custLike
149 *
150 * }</pre>
151 * <p>
152 * Find orders and also fetch the customer with a named bind parameter. This
153 * will fetch and populate both the order and customer objects.
154 * </p>
155 * <pre>{@code
156 *
157 * fetch customer
158 * where customer.id = :custId
159 *
160 * }</pre>
161 * <p>
162 * Find orders and also fetch the customer, customer shippingAddress, order
163 * details and related product. Note that customer and product objects will be
164 * "Partial Objects" with only some of their properties populated. The customer
165 * objects will have their id, name and shipping address populated. The product
166 * objects (associated with each order detail) will have their id, sku and name
167 * populated.
168 * </p>
169 * <pre>{@code
170 *
171 * fetch customer (name)
172 * fetch customer.shippingAddress
173 * fetch details
174 * fetch details.product (sku, name)
175 *
176 * }</pre>
177 *
178 * @param <T> the type of Entity bean this query will fetch.
179 */
180public interface Query<T> {
181
182  /**
183   * The lock type (strength) to use with query FOR UPDATE row locking.
184   */
185  enum LockType {
186    /**
187     * The default lock type being either UPDATE or NO_KEY_UPDATE based on
188     * PlatformConfig.forUpdateNoKey configuration (Postgres option).
189     */
190    DEFAULT,
191
192    /**
193     * FOR UPDATE.
194     */
195    UPDATE,
196
197    /**
198     * FOR NO KEY UPDATE (Postgres only).
199     */
200    NO_KEY_UPDATE,
201
202    /**
203     * FOR SHARE (Postgres only).
204     */
205    SHARE,
206
207    /**
208     * FOR KEY SHARE (Postgres only).
209     */
210    KEY_SHARE
211  }
212
213  /**
214   * FOR UPDATE wait mode.
215   */
216  enum LockWait {
217    /**
218     * Standard For update clause.
219     */
220    WAIT,
221
222    /**
223     * For update with No Wait option.
224     */
225    NOWAIT,
226
227    /**
228     * For update with Skip Locked option.
229     */
230    SKIPLOCKED
231  }
232
233  /**
234   * Set RawSql to use for this query.
235   */
236  Query<T> setRawSql(RawSql rawSql);
237
238  /**
239   * Perform an 'As of' query using history tables to return the object graph
240   * as of a time in the past.
241   * <p>
242   * To perform this query the DB must have underlying history tables.
243   * </p>
244   *
245   * @param asOf the date time in the past at which you want to view the data
246   */
247  Query<T> asOf(Timestamp asOf);
248
249  /**
250   * Execute the query against the draft set of tables.
251   */
252  Query<T> asDraft();
253
254  /**
255   * Convert the query to a DTO bean query.
256   * <p>
257   * We effectively use the underlying ORM query to build the SQL and then execute
258   * and map it into DTO beans.
259   */
260  <D> DtoQuery<D> asDto(Class<D> dtoClass);
261
262  /**
263   * Convert the query to a UpdateQuery.
264   * <p>
265   * Typically this is used with query beans to covert a query bean
266   * query into an UpdateQuery like the examples below.
267   * </p>
268   *
269   * <pre>{@code
270   *
271   *  int rowsUpdated = new QCustomer()
272   *       .name.startsWith("Rob")
273   *       .asUpdate()
274   *       .set("active", false)
275   *       .update();;
276   *
277   * }</pre>
278   *
279   * <pre>{@code
280   *
281   *   int rowsUpdated = new QContact()
282   *       .notes.note.startsWith("Make Inactive")
283   *       .email.endsWith("@foo.com")
284   *       .customer.id.equalTo(42)
285   *       .asUpdate()
286   *       .set("inactive", true)
287   *       .setRaw("email = lower(email)")
288   *       .update();
289   *
290   * }</pre>
291   */
292  UpdateQuery<T> asUpdate();
293
294  /**
295   * Cancel the query execution if supported by the underlying database and
296   * driver.
297   * <p>
298   * This must be called from a different thread to the query executor.
299   * </p>
300   */
301  void cancel();
302
303  /**
304   * Return a copy of the query.
305   * <p>
306   * This is so that you can use a Query as a "prototype" for creating other
307   * query instances. You could create a Query with various where expressions
308   * and use that as a "prototype" - using this copy() method to create a new
309   * instance that you can then add other expressions then execute.
310   * </p>
311   */
312  Query<T> copy();
313
314  /**
315   * Specify the PersistenceContextScope to use for this query.
316   * <p/>
317   * When this is not set the 'default' configured on {@link io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)}
318   * is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
319   * <p/>
320   * Note that the same persistence Context is used for subsequent lazy loading and query join queries.
321   * <p/>
322   * Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for
323   * queries executed as #findIterate, #findEach, #findEachWhile.
324   *
325   * @param scope The scope to use for this query and subsequent lazy loading.
326   */
327  Query<T> setPersistenceContextScope(PersistenceContextScope scope);
328
329  /**
330   * Set the index(es) to search for a document store which uses partitions.
331   * <p>
332   * For example, when executing a query against ElasticSearch with daily indexes we can
333   * explicitly specify the indexes to search against.
334   * </p>
335   * <pre>{@code
336   *
337   *   // explicitly specify the indexes to search
338   *   query.setDocIndexName("logstash-2016.11.5,logstash-2016.11.6")
339   *
340   *   // search today's index
341   *   query.setDocIndexName("$today")
342   *
343   *   // search the last 3 days
344   *   query.setDocIndexName("$last-3")
345   *
346   * }</pre>
347   * <p>
348   * If the indexName is specified with ${daily} e.g. "logstash-${daily}" ... then we can use
349   * $today and $last-x as the search docIndexName like the examples below.
350   * </p>
351   * <pre>{@code
352   *
353   *   // search today's index
354   *   query.setDocIndexName("$today")
355   *
356   *   // search the last 3 days
357   *   query.setDocIndexName("$last-3")
358   *
359   * }</pre>
360   *
361   * @param indexName The index or indexes to search against
362   * @return This query
363   */
364  Query<T> setDocIndexName(String indexName);
365
366  /**
367   * Return the ExpressionFactory used by this query.
368   */
369  ExpressionFactory getExpressionFactory();
370
371  /**
372   * Returns true if this query was tuned by autoTune.
373   */
374  boolean isAutoTuned();
375
376  /**
377   * Explicitly specify whether to use AutoTune for this query.
378   * <p>
379   * If you do not call this method on a query the "Implicit AutoTune mode" is
380   * used to determine if AutoTune should be used for a given query.
381   * </p>
382   * <p>
383   * AutoTune can add additional fetch paths to the query and specify which
384   * properties are included for each path. If you have explicitly defined some
385   * fetch paths AutoTune will not remove them.
386   * </p>
387   */
388  Query<T> setAutoTune(boolean autoTune);
389
390  /**
391   * Execute the query allowing properties with invalid JSON to be collected and not fail the query.
392   * <pre>{@code
393   *
394   *   // fetch a bean with JSON content
395   *   EBasicJsonList bean= DB.find(EBasicJsonList.class)
396   *       .setId(42)
397   *       .setAllowLoadErrors()  // collect errors into bean state if we have invalid JSON
398   *       .findOne();
399   *
400   *
401   *   // get the invalid JSON errors from the bean state
402   *   Map<String, Exception> errors = server().getBeanState(bean).getLoadErrors();
403   *
404   *   // If this map is not empty tell we have invalid JSON
405   *   // and should try and fix the JSON content or inform the user
406   *
407   * }</pre>
408   */
409  Query<T> setAllowLoadErrors();
410
411  /**
412   * Set the default lazy loading batch size to use.
413   * <p>
414   * When lazy loading is invoked on beans loaded by this query then this sets the
415   * batch size used to load those beans.
416   *
417   * @param lazyLoadBatchSize the number of beans to lazy load in a single batch
418   */
419  Query<T> setLazyLoadBatchSize(int lazyLoadBatchSize);
420
421  /**
422   * Execute the query including soft deleted rows.
423   * <p>
424   * This means that Ebean will not add any predicates to the query for filtering out
425   * soft deleted rows. You can still add your own predicates for the deleted properties
426   * and effectively you have full control over the query to include or exclude soft deleted
427   * rows as needed for a given use case.
428   * </p>
429   */
430  Query<T> setIncludeSoftDeletes();
431
432  /**
433   * Disable read auditing for this query.
434   * <p>
435   * This is intended to be used when the query is not a user initiated query and instead
436   * part of the internal processing in an application to load a cache or document store etc.
437   * In these cases we don't want the query to be part of read auditing.
438   * </p>
439   */
440  Query<T> setDisableReadAuditing();
441
442  /**
443   * Specify the properties to fetch on the root level entity bean in comma delimited format.
444   * <p>
445   * The Id property is automatically included in the properties to fetch unless setDistinct(true)
446   * is set on the query.
447   * </p>
448   * <p>
449   * Use {@link #fetch(String, String)} to specify specific properties to fetch
450   * on other non-root level paths of the object graph.
451   * </p>
452   * <pre>{@code
453   *
454   * List<Customer> customers = DB.find(Customer.class)
455   *     // Only fetch the customer id, name and status.
456   *     // This is described as a "Partial Object"
457   *     .select("name, status")
458   *     .where.ilike("name", "rob%")
459   *     .findList();
460   *
461   * }</pre>
462   *
463   * @param fetchProperties the properties to fetch for this bean (* = all properties).
464   */
465  Query<T> select(String fetchProperties);
466
467  /**
468   * Apply the fetchGroup which defines what part of the object graph to load.
469   */
470  Query<T> select(FetchGroup<T> fetchGroup);
471
472  /**
473   * Specify a path to fetch eagerly including specific properties.
474   * <p>
475   * Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
476   * not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
477   * will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
478   * </p>
479   * <pre>{@code
480   *
481   * // query orders...
482   * List<Order> orders = DB.find(Order.class)
483   *       // fetch the customer...
484   *       // ... getting the customers name and phone number
485   *       .fetch("customer", "name, phoneNumber")
486   *
487   *       // ... also fetch the customers billing address (* = all properties)
488   *       .fetch("customer.billingAddress", "*")
489   *       .findList();
490   * }</pre>
491   * <p>
492   * If columns is null or "*" then all columns/properties for that path are fetched.
493   * </p>
494   * <pre>{@code
495   *
496   * // fetch customers (their id, name and status)
497   * List<Customer> customers = DB.find(Customer.class)
498   *     .select("name, status")
499   *     .fetch("contacts", "firstName,lastName,email")
500   *     .findList();
501   *
502   * }</pre>
503   *
504   * @param path            the property path we wish to fetch eagerly.
505   * @param fetchProperties properties of the associated bean that you want to include in the
506   *                        fetch (* means all properties, null also means all properties).
507   */
508  Query<T> fetch(String path, String fetchProperties);
509
510  /**
511   * Fetch the path and properties using a "query join" (separate SQL query).
512   * <p>
513   * This is the same as:
514   * </p>
515   * <pre>{@code
516   *
517   *  fetch(path, fetchProperties, FetchConfig.ofQuery())
518   *
519   * }</pre>
520   * <p>
521   * This would be used instead of a fetch() when we use a separate SQL query to fetch this
522   * part of the object graph rather than a SQL join.
523   * </p>
524   * <p>
525   * We might typically get a performance benefit when the path to fetch is a OneToMany
526   * or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
527   * is high.
528   * </p>
529   *
530   * @param path            the property path we wish to fetch eagerly.
531   * @param fetchProperties properties of the associated bean that you want to include in the
532   *                        fetch (* means all properties, null also means all properties).
533   */
534  Query<T> fetchQuery(String path, String fetchProperties);
535
536  /**
537   * Fetch the path and properties using L2 bean cache.
538   *
539   * @param path            The path of the beans we are fetching from L2 cache.
540   * @param fetchProperties The properties that should be loaded.
541   */
542  Query<T> fetchCache(String path, String fetchProperties);
543
544  /**
545   * Fetch the path and properties lazily (via batch lazy loading).
546   * <p>
547   * This is the same as:
548   * </p>
549   * <pre>{@code
550   *
551   *  fetch(path, fetchProperties, FetchConfig.ofLazy())
552   *
553   * }</pre>
554   * <p>
555   * The reason for using fetchLazy() is to either:
556   * </p>
557   * <ul>
558   * <li>Control/tune what is fetched as part of lazy loading</li>
559   * <li>Make use of the L2 cache, build this part of the graph from L2 cache</li>
560   * </ul>
561   *
562   * @param path            the property path we wish to fetch lazily.
563   * @param fetchProperties properties of the associated bean that you want to include in the
564   *                        fetch (* means all properties, null also means all properties).
565   */
566  Query<T> fetchLazy(String path, String fetchProperties);
567
568  /**
569   * Additionally specify a FetchConfig to use a separate query or lazy loading
570   * to load this path.
571   * <pre>{@code
572   *
573   * // fetch customers (their id, name and status)
574   * List<Customer> customers = DB.find(Customer.class)
575   *     .select("name, status")
576   *     .fetch("contacts", "firstName,lastName,email", FetchConfig.ofLazy(10))
577   *     .findList();
578   *
579   * }</pre>
580   *
581   * @param path the property path we wish to fetch eagerly.
582   */
583  Query<T> fetch(String path, String fetchProperties, FetchConfig fetchConfig);
584
585  /**
586   * Specify a path to fetch eagerly including all its properties.
587   * <p>
588   * Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
589   * not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
590   * will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
591   * </p>
592   * <pre>{@code
593   *
594   * // fetch customers (their id, name and status)
595   * List<Customer> customers = DB.find(Customer.class)
596   *     // eager fetch the contacts
597   *     .fetch("contacts")
598   *     .findList();
599   *
600   * }</pre>
601   *
602   * @param path the property path we wish to fetch eagerly.
603   */
604  Query<T> fetch(String path);
605
606  /**
607   * Fetch the path eagerly using a "query join" (separate SQL query).
608   * <p>
609   * This is the same as:
610   * </p>
611   * <pre>{@code
612   *
613   *  fetch(path, FetchConfig.ofQuery())
614   *
615   * }</pre>
616   * <p>
617   * This would be used instead of a fetch() when we use a separate SQL query to fetch this
618   * part of the object graph rather than a SQL join.
619   * </p>
620   * <p>
621   * We might typically get a performance benefit when the path to fetch is a OneToMany
622   * or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
623   * is high.
624   * </p>
625   *
626   * @param path the property path we wish to fetch eagerly
627   */
628  Query<T> fetchQuery(String path);
629
630  /**
631   * Fetch the path eagerly using L2 cache.
632   */
633  Query<T> fetchCache(String path);
634
635  /**
636   * Fetch the path lazily (via batch lazy loading).
637   * <p>
638   * This is the same as:
639   * </p>
640   * <pre>{@code
641   *
642   *  fetch(path, FetchConfig.ofLazy())
643   *
644   * }</pre>
645   * <p>
646   * The reason for using fetchLazy() is to either:
647   * </p>
648   * <ul>
649   * <li>Control/tune what is fetched as part of lazy loading</li>
650   * <li>Make use of the L2 cache, build this part of the graph from L2 cache</li>
651   * </ul>
652   *
653   * @param path the property path we wish to fetch lazily.
654   */
655  Query<T> fetchLazy(String path);
656
657  /**
658   * Additionally specify a JoinConfig to specify a "query join" and or define
659   * the lazy loading query.
660   * <pre>{@code
661   *
662   * // fetch customers (their id, name and status)
663   * List<Customer> customers = DB.find(Customer.class)
664   *     // lazy fetch contacts with a batch size of 100
665   *     .fetch("contacts", FetchConfig.ofLazy(100))
666   *     .findList();
667   *
668   * }</pre>
669   */
670  Query<T> fetch(String path, FetchConfig fetchConfig);
671
672  /**
673   * Apply the path properties replacing the select and fetch clauses.
674   * <p>
675   * This is typically used when the FetchPath is applied to both the query and the JSON output.
676   * </p>
677   */
678  Query<T> apply(FetchPath fetchPath);
679
680  /**
681   * Execute the query using the given transaction.
682   */
683  Query<T> usingTransaction(Transaction transaction);
684
685  /**
686   * Execute the query using the given connection.
687   */
688  Query<T> usingConnection(Connection connection);
689
690  /**
691   * Execute the query using the given database.
692   */
693  Query<T> usingDatabase(Database database);
694
695  /**
696   * Execute the query returning the list of Id's.
697   * <p>
698   * This query will execute against the Database that was used to create it.
699   * </p>
700   */
701  @Nonnull
702  <A> List<A> findIds();
703
704  /**
705   * Execute the query iterating over the results.
706   * <p>
707   * Note that findIterate (and findEach and findEachWhile) uses a "per graph"
708   * persistence context scope and adjusts jdbc fetch buffer size for large
709   * queries. As such it is better to use findList for small queries.
710   * </p>
711   * <p>
712   * Remember that with {@link QueryIterator} you must call {@link QueryIterator#close()}
713   * when you have finished iterating the results (typically in a finally block).
714   * </p>
715   * <p>
716   * findEach() and findEachWhile() are preferred to findIterate() as they ensure
717   * the jdbc statement and resultSet are closed at the end of the iteration.
718   * </p>
719   * <p>
720   * This query will execute against the Database that was used to create it.
721   * </p>
722   * <pre>{@code
723   *
724   *  Query<Customer> query = DB.find(Customer.class)
725   *     .where().eq("status", Status.NEW)
726   *     .order().asc("id");
727   *
728   *  // use try with resources to ensure QueryIterator is closed
729   *
730   *  try (QueryIterator<Customer> it = query.findIterate()) {
731   *    while (it.hasNext()) {
732   *      Customer customer = it.next();
733   *      // do something with customer ...
734   *    }
735   *  }
736   *
737   * }</pre>
738   */
739  @Nonnull
740  QueryIterator<T> findIterate();
741
742  /**
743   * Execute the query returning the result as a Stream.
744   * <p>
745   * Note that this can support very large queries iterating
746   * any number of results. To do so internally it can use
747   * multiple persistence contexts.
748   * </p>
749   * <pre>{@code
750   *
751   *  // use try with resources to ensure Stream is closed
752   *
753   *  try (Stream<Customer> stream = query.findStream()) {
754   *    stream
755   *    .map(...)
756   *    .collect(...);
757   *  }
758   *
759   * }</pre>
760   */
761  @Nonnull
762  Stream<T> findStream();
763
764  /**
765   * Deprecated - migrate to findStream.
766   * <p>
767   * Execute the query returning the result as a Stream.
768   * <p>
769   * Note that this uses multiple persistence contexts such that we can use
770   * it with a large number of results.
771   * </p>
772   * <pre>{@code
773   *
774   *  // use try with resources to ensure Stream is closed
775   *
776   *  try (Stream<Customer> stream = query.findLargeStream()) {
777   *    stream
778   *    .map(...)
779   *    .collect(...);
780   *  }
781   *
782   * }</pre>
783   */
784  @Nonnull
785  @Deprecated
786  Stream<T> findLargeStream();
787
788  /**
789   * Execute the query processing the beans one at a time.
790   * <p>
791   * This method is appropriate to process very large query results as the
792   * beans are consumed one at a time and do not need to be held in memory
793   * (unlike #findList #findSet etc)
794   * </p>
795   * <p>
796   * Note that findEach (and findEachWhile and findIterate) uses a "per graph"
797   * persistence context scope and adjusts jdbc fetch buffer size for large
798   * queries. As such it is better to use findList for small queries.
799   * </p>
800   * <p>
801   * Note that internally Ebean can inform the JDBC driver that it is expecting larger
802   * resultSet and specifically for MySQL this hint is required to stop it's JDBC driver
803   * from buffering the entire resultSet. As such, for smaller resultSets findList() is
804   * generally preferable.
805   * </p>
806   * <p>
807   * Compared with #findEachWhile this will always process all the beans where as
808   * #findEachWhile provides a way to stop processing the query result early before
809   * all the beans have been read.
810   * </p>
811   * <p>
812   * This method is functionally equivalent to findIterate() but instead of using an
813   * iterator uses the Consumer interface which is better suited to use with closures.
814   * </p>
815   * <pre>{@code
816   *
817   *  DB.find(Customer.class)
818   *     .where().eq("status", Status.NEW)
819   *     .order().asc("id")
820   *     .findEach((Customer customer) -> {
821   *
822   *       // do something with customer
823   *       System.out.println("-- visit " + customer);
824   *     });
825   *
826   * }</pre>
827   *
828   * @param consumer the consumer used to process the queried beans.
829   */
830  void findEach(Consumer<T> consumer);
831
832  /**
833   * Execute findEach streaming query batching the results for consuming.
834   * <p>
835   * This query execution will stream the results and is suited to consuming
836   * large numbers of results from the database.
837   * <p>
838   * Typically we use this batch consumer when we want to do further processing on
839   * the beans and want to do that processing in batch form, for example - 100 at
840   * a time.
841   *
842   * @param batch    The number of beans processed in the batch
843   * @param consumer Process the batch of beans
844   */
845  void findEach(int batch, Consumer<List<T>> consumer);
846
847  /**
848   * Execute the query using callbacks to a visitor to process the resulting
849   * beans one at a time.
850   * <p>
851   * Note that findEachWhile (and findEach and findIterate) uses a "per graph"
852   * persistence context scope and adjusts jdbc fetch buffer size for large
853   * queries. As such it is better to use findList for small queries.
854   * </p>
855   * <p>
856   * This method is functionally equivalent to findIterate() but instead of using an
857   * iterator uses the Predicate interface which is better suited to use with closures.
858   * </p>
859   * <pre>{@code
860   *
861   *  DB.find(Customer.class)
862   *     .fetchQuery("contacts")
863   *     .where().eq("status", Status.NEW)
864   *     .order().asc("id")
865   *     .setMaxRows(2000)
866   *     .findEachWhile((Customer customer) -> {
867   *
868   *       // do something with customer
869   *       System.out.println("-- visit " + customer);
870   *
871   *       // return true to continue processing or false to stop
872   *       return (customer.getId() < 40);
873   *     });
874   *
875   * }</pre>
876   *
877   * @param consumer the consumer used to process the queried beans.
878   */
879  void findEachWhile(Predicate<T> consumer);
880
881  /**
882   * Execute the query returning the list of objects.
883   * <p>
884   * This query will execute against the Database that was used to create it.
885   * </p>
886   * <pre>{@code
887   *
888   * List<Customer> customers = DB.find(Customer.class)
889   *     .where().ilike("name", "rob%")
890   *     .findList();
891   *
892   * }</pre>
893   */
894  @Nonnull
895  List<T> findList();
896
897  /**
898   * Execute the query returning the set of objects.
899   * <p>
900   * This query will execute against the Database that was used to create it.
901   * </p>
902   * <pre>{@code
903   *
904   * Set<Customer> customers = DB.find(Customer.class)
905   *     .where().ilike("name", "rob%")
906   *     .findSet();
907   *
908   * }</pre>
909   */
910  @Nonnull
911  Set<T> findSet();
912
913  /**
914   * Execute the query returning a map of the objects.
915   * <p>
916   * This query will execute against the Database that was used to create it.
917   * </p>
918   * <p>
919   * You can use setMapKey() so specify the property values to be used as keys
920   * on the map. If one is not specified then the id property is used.
921   * </p>
922   * <pre>{@code
923   *
924   * Map<String, Product> map = DB.find(Product.class)
925   *     .setMapKey("sku")
926   *     .findMap();
927   *
928   * }</pre>
929   */
930  @Nonnull
931  <K> Map<K, T> findMap();
932
933  /**
934   * Execute the query returning a list of values for a single property.
935   * <p>
936   * <h3>Example 1:</h3>
937   * <pre>{@code
938   *
939   *  List<String> names =
940   *    DB.find(Customer.class)
941   *      .select("name")
942   *      .order().asc("name")
943   *      .findSingleAttributeList();
944   *
945   * }</pre>
946   * <p>
947   * <h3>Example 2:</h3>
948   * <pre>{@code
949   *
950   *  List<String> names =
951   *    DB.find(Customer.class)
952   *      .setDistinct(true)
953   *      .select("name")
954   *      .where().eq("status", Customer.Status.NEW)
955   *      .order().asc("name")
956   *      .setMaxRows(100)
957   *      .findSingleAttributeList();
958   *
959   * }</pre>
960   *
961   * @return the list of values for the selected property
962   */
963  @Nonnull
964  <A> List<A> findSingleAttributeList();
965
966  /**
967   * Execute a query returning a single value of a single property/column.
968   * <p>
969   * <pre>{@code
970   *
971   *  String name =
972   *    DB.find(Customer.class)
973   *      .select("name")
974   *      .where().eq("id", 42)
975   *      .findSingleAttribute();
976   *
977   * }</pre>
978   */
979  <A> A findSingleAttribute();
980
981  /**
982   * Return true if this is countDistinct query.
983   */
984  boolean isCountDistinct();
985
986  /**
987   * Execute the query returning true if a row is found.
988   * <p>
989   * The query is executed using max rows of 1 and will only select the id property.
990   * This method is really just a convenient way to optimise a query to perform a
991   * 'does a row exist in the db' check.
992   * </p>
993   *
994   * <h2>Example using a query bean:</h2>
995   * <pre>{@code
996   *
997   *   boolean userExists =
998   *     new QContact()
999   *       .email.equalTo("rob@foo.com")
1000   *       .exists();
1001   *
1002   * }</pre>
1003   *
1004   * <h2>Example:</h2>
1005   * <pre>{@code
1006   *
1007   *   boolean userExists = query()
1008   *     .where().eq("email", "rob@foo.com")
1009   *     .exists();
1010   *
1011   * }</pre>
1012   *
1013   * @return True if the query finds a matching row in the database
1014   */
1015  boolean exists();
1016
1017  /**
1018   * Execute the query returning either a single bean or null (if no matching
1019   * bean is found).
1020   * <p>
1021   * If more than 1 row is found for this query then a NonUniqueResultException is
1022   * thrown.
1023   * </p>
1024   * <p>
1025   * This is useful when your predicates dictate that your query should only
1026   * return 0 or 1 results.
1027   * </p>
1028   * <pre>{@code
1029   *
1030   * // assuming the sku of products is unique...
1031   * Product product = DB.find(Product.class)
1032   *         .where().eq("sku", "aa113")
1033   *         .findOne();
1034   * ...
1035   * }</pre>
1036   * <p>
1037   * It is also useful with finding objects by their id when you want to specify
1038   * further join information.
1039   * </p>
1040   * <pre>{@code
1041   *
1042   * // Fetch order 1 and additionally fetch join its order details...
1043   * Order order = DB.find(Order.class)
1044   *       .setId(1)
1045   *       .fetch("details")
1046   *       .findOne();
1047   *
1048   * // the order details were eagerly loaded
1049   * List<OrderDetail> details = order.getDetails();
1050   * ...
1051   * }</pre>
1052   *
1053   * @throws NonUniqueResultException if more than one result was found
1054   */
1055  @Nullable
1056  T findOne();
1057
1058  /**
1059   * Execute the query returning an optional bean.
1060   */
1061  @Nonnull
1062  Optional<T> findOneOrEmpty();
1063
1064  /**
1065   * Return versions of a @History entity bean.
1066   * <p>
1067   * Note that this query will work against view based history implementations
1068   * but not sql2011 standards based implementations that require a start and
1069   * end timestamp to be specified.
1070   * </p>
1071   * <p>
1072   * Generally this query is expected to be a find by id or unique predicates query.
1073   * It will execute the query against the history returning the versions of the bean.
1074   * </p>
1075   */
1076  @Nonnull
1077  List<Version<T>> findVersions();
1078
1079  /**
1080   * Return versions of a @History entity bean between the 2 timestamps.
1081   * <p>
1082   * Generally this query is expected to be a find by id or unique predicates query.
1083   * It will execute the query against the history returning the versions of the bean.
1084   * </p>
1085   */
1086  @Nonnull
1087  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
1088
1089  /**
1090   * Execute as a delete query deleting the 'root level' beans that match the predicates
1091   * in the query.
1092   * <p>
1093   * Note that if the query includes joins then the generated delete statement may not be
1094   * optimal depending on the database platform.
1095   * </p>
1096   *
1097   * @return the number of beans/rows that were deleted.
1098   */
1099  int delete();
1100
1101  /**
1102   * Execute as a delete query returning the number of rows deleted using the given transaction.
1103   * <p>
1104   * Note that if the query includes joins then the generated delete statement may not be
1105   * optimal depending on the database platform.
1106   * </p>
1107   *
1108   * @return the number of beans/rows that were deleted.
1109   */
1110  int delete(Transaction transaction);
1111
1112  /**
1113   * Execute the UpdateQuery returning the number of rows updated.
1114   *
1115   * @return the number of beans/rows updated.
1116   */
1117  int update();
1118
1119  /**
1120   * Execute the UpdateQuery returning the number of rows updated using the given transaction.
1121   *
1122   * @return the number of beans/rows updated.
1123   */
1124  int update(Transaction transaction);
1125
1126  /**
1127   * Return the count of entities this query should return.
1128   * <p>
1129   * This is the number of 'top level' or 'root level' entities.
1130   * </p>
1131   */
1132  int findCount();
1133
1134  /**
1135   * Execute find row count query in a background thread.
1136   * <p>
1137   * This returns a Future object which can be used to cancel, check the
1138   * execution status (isDone etc) and get the value (with or without a
1139   * timeout).
1140   * </p>
1141   *
1142   * @return a Future object for the row count query
1143   */
1144  @Nonnull
1145  FutureRowCount<T> findFutureCount();
1146
1147  /**
1148   * Execute find Id's query in a background thread.
1149   * <p>
1150   * This returns a Future object which can be used to cancel, check the
1151   * execution status (isDone etc) and get the value (with or without a
1152   * timeout).
1153   * </p>
1154   *
1155   * @return a Future object for the list of Id's
1156   */
1157  @Nonnull
1158  FutureIds<T> findFutureIds();
1159
1160  /**
1161   * Execute find list query in a background thread.
1162   * <p>
1163   * This query will execute in it's own PersistenceContext and using its own transaction.
1164   * What that means is that it will not share any bean instances with other queries.
1165   * </p>
1166   *
1167   * @return a Future object for the list result of the query
1168   */
1169  @Nonnull
1170  FutureList<T> findFutureList();
1171
1172  /**
1173   * Return a PagedList for this query using firstRow and maxRows.
1174   * <p>
1175   * The benefit of using this over findList() is that it provides functionality to get the
1176   * total row count etc.
1177   * </p>
1178   * <p>
1179   * If maxRows is not set on the query prior to calling findPagedList() then a
1180   * PersistenceException is thrown.
1181   * </p>
1182   * <pre>{@code
1183   *
1184   *  PagedList<Order> pagedList = DB.find(Order.class)
1185   *       .setFirstRow(50)
1186   *       .setMaxRows(20)
1187   *       .findPagedList();
1188   *
1189   *       // fetch the total row count in the background
1190   *       pagedList.loadRowCount();
1191   *
1192   *       List<Order> orders = pagedList.getList();
1193   *       int totalRowCount = pagedList.getTotalRowCount();
1194   *
1195   * }</pre>
1196   *
1197   * @return The PagedList
1198   */
1199  @Nonnull
1200  PagedList<T> findPagedList();
1201
1202  /**
1203   * Set a named bind parameter. Named parameters have a colon to prefix the name.
1204   * <pre>{@code
1205   *
1206   * // a query with a named parameter
1207   * String oql = "find order where status = :orderStatus";
1208   *
1209   * List<Order> list = DB.find(Order.class, oql)
1210   *   .setParameter("orderStatus", OrderStatus.NEW)
1211   *   .findList();
1212   *
1213   * }</pre>
1214   *
1215   * @param name  the parameter name
1216   * @param value the parameter value
1217   */
1218  Query<T> setParameter(String name, Object value);
1219
1220  /**
1221   * Set an ordered bind parameter according to its position. Note that the
1222   * position starts at 1 to be consistent with JDBC PreparedStatement. You need
1223   * to set a parameter value for each ? you have in the query.
1224   * <pre>{@code
1225   *
1226   * // a query with a positioned parameter
1227   * String oql = "where status = ? order by id desc";
1228   *
1229   * List<Order> list = DB.createQuery(Order.class, oql)
1230   *   .setParameter(1, OrderStatus.NEW)
1231   *   .findList();
1232   *
1233   * }</pre>
1234   *
1235   * @param position the parameter bind position starting from 1 (not 0)
1236   * @param value    the parameter bind value.
1237   */
1238  Query<T> setParameter(int position, Object value);
1239
1240  /**
1241   * Bind the next positioned parameter.
1242   *
1243   * <pre>{@code
1244   *
1245   * // a query with a positioned parameters
1246   * String oql = "where status = ? and name = ?";
1247   *
1248   * List<Order> list = DB.createQuery(Order.class, oql)
1249   *   .setParameter(OrderStatus.NEW)
1250   *   .setParameter("Rob")
1251   *   .findList();
1252   *
1253   * }</pre>
1254   */
1255  Query<T> setParameter(Object value);
1256
1257  /**
1258   * Bind all the positioned parameters.
1259   * <p>
1260   * A convenience for multiple calls to {@link #setParameter(Object)}
1261   */
1262  Query<T> setParameters(Object... values);
1263
1264  /**
1265   * Set the Id value to query. This is used with findOne().
1266   * <p>
1267   * You can use this to have further control over the query. For example adding
1268   * fetch joins.
1269   * </p>
1270   * <pre>{@code
1271   *
1272   * Order order = DB.find(Order.class)
1273   *     .setId(1)
1274   *     .fetch("details")
1275   *     .findOne();
1276   *
1277   * // the order details were eagerly fetched
1278   * List<OrderDetail> details = order.getDetails();
1279   *
1280   * }</pre>
1281   */
1282  Query<T> setId(Object id);
1283
1284  /**
1285   * Return the Id value.
1286   */
1287  Object getId();
1288
1289  /**
1290   * Add a single Expression to the where clause returning the query.
1291   * <pre>{@code
1292   *
1293   * List<Order> newOrders = DB.find(Order.class)
1294   *            .where().eq("status", Order.NEW)
1295   *            .findList();
1296   * ...
1297   *
1298   * }</pre>
1299   */
1300  Query<T> where(Expression expression);
1301
1302  /**
1303   * Add Expressions to the where clause with the ability to chain on the
1304   * ExpressionList. You can use this for adding multiple expressions to the
1305   * where clause.
1306   * <pre>{@code
1307   *
1308   * List<Order> orders = DB.find(Order.class)
1309   *     .where()
1310   *       .eq("status", Order.NEW)
1311   *       .ilike("customer.name","rob%")
1312   *     .findList();
1313   *
1314   * }</pre>
1315   *
1316   * @return The ExpressionList for adding expressions to.
1317   * @see Expr
1318   */
1319  ExpressionList<T> where();
1320
1321  /**
1322   * Add Full text search expressions for Document store queries.
1323   * <p>
1324   * This is currently ElasticSearch only and provides the full text
1325   * expressions such as Match and Multi-Match.
1326   * </p>
1327   * <p>
1328   * This automatically makes this query a "Doc Store" query and will execute
1329   * against the document store (ElasticSearch).
1330   * </p>
1331   * <p>
1332   * Expressions added here are added to the "query" section of an ElasticSearch
1333   * query rather than the "filter" section.
1334   * </p>
1335   * <p>
1336   * Expressions added to the where() are added to the "filter" section of an
1337   * ElasticSearch query.
1338   * </p>
1339   */
1340  ExpressionList<T> text();
1341
1342  /**
1343   * This applies a filter on the 'many' property list rather than the root
1344   * level objects.
1345   * <p>
1346   * Typically you will use this in a scenario where the cardinality is high on
1347   * the 'many' property you wish to join to. Say you want to fetch customers
1348   * and their associated orders... but instead of getting all the orders for
1349   * each customer you only want to get the new orders they placed since last
1350   * week. In this case you can use filterMany() to filter the orders.
1351   * </p>
1352   * <pre>{@code
1353   *
1354   * List<Customer> list = DB.find(Customer.class)
1355   *     .fetch("orders")
1356   *     .where().ilike("name", "rob%")
1357   *     .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek)
1358   *     .findList();
1359   *
1360   * }</pre>
1361   * <p>
1362   * Please note you have to be careful that you add expressions to the correct
1363   * expression list - as there is one for the 'root level' and one for each
1364   * filterMany that you have.
1365   * </p>
1366   *
1367   * @param propertyName the name of the many property that you want to have a filter on.
1368   * @return the expression list that you add filter expressions for the many to.
1369   */
1370  ExpressionList<T> filterMany(String propertyName);
1371
1372  /**
1373   * Add Expressions to the Having clause return the ExpressionList.
1374   * <p>
1375   * Currently only beans based on raw sql will use the having clause.
1376   * </p>
1377   * <p>
1378   * Note that this returns the ExpressionList (so you can add multiple
1379   * expressions to the query in a fluent API way).
1380   * </p>
1381   *
1382   * @return The ExpressionList for adding more expressions to.
1383   * @see Expr
1384   */
1385  ExpressionList<T> having();
1386
1387  /**
1388   * Add an expression to the having clause returning the query.
1389   * <p>
1390   * Currently only beans based on raw sql will use the having clause.
1391   * </p>
1392   * <p>
1393   * This is similar to {@link #having()} except it returns the query rather
1394   * than the ExpressionList. This is useful when you want to further specify
1395   * something on the query.
1396   * </p>
1397   *
1398   * @param addExpressionToHaving the expression to add to the having clause.
1399   * @return the Query object
1400   */
1401  Query<T> having(Expression addExpressionToHaving);
1402
1403  /**
1404   * Set the order by clause replacing the existing order by clause if there is
1405   * one.
1406   * <p>
1407   * This follows SQL syntax using commas between each property with the
1408   * optional asc and desc keywords representing ascending and descending order
1409   * respectively.
1410   */
1411  Query<T> orderBy(String orderByClause);
1412
1413  /**
1414   * Set the order by clause replacing the existing order by clause if there is
1415   * one.
1416   * <p>
1417   * This follows SQL syntax using commas between each property with the
1418   * optional asc and desc keywords representing ascending and descending order
1419   * respectively.
1420   */
1421  Query<T> order(String orderByClause);
1422
1423  /**
1424   * Return the OrderBy so that you can append an ascending or descending
1425   * property to the order by clause.
1426   * <p>
1427   * This will never return a null. If no order by clause exists then an 'empty'
1428   * OrderBy object is returned.
1429   * <p>
1430   * This is the same as <code>orderBy()</code>
1431   */
1432  OrderBy<T> order();
1433
1434  /**
1435   * Return the OrderBy so that you can append an ascending or descending
1436   * property to the order by clause.
1437   * <p>
1438   * This will never return a null. If no order by clause exists then an 'empty'
1439   * OrderBy object is returned.
1440   * <p>
1441   * This is the same as <code>order()</code>
1442   */
1443  OrderBy<T> orderBy();
1444
1445  /**
1446   * Set an OrderBy object to replace any existing OrderBy clause.
1447   */
1448  Query<T> setOrder(OrderBy<T> orderBy);
1449
1450  /**
1451   * Set an OrderBy object to replace any existing OrderBy clause.
1452   */
1453  Query<T> setOrderBy(OrderBy<T> orderBy);
1454
1455  /**
1456   * Set whether this query uses DISTINCT.
1457   * <p>
1458   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
1459   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
1460   * </p>
1461   * <pre>{@code
1462   *
1463   *   List<Customer> customers =
1464   *       DB.find(Customer.class)
1465   *          .setDistinct(true)
1466   *          .select("name")
1467   *          .findList();
1468   *
1469   * }</pre>
1470   */
1471  Query<T> setDistinct(boolean isDistinct);
1472
1473  /**
1474   * Extended version for setDistinct in conjunction with "findSingleAttributeList";
1475   *
1476   * <pre>{@code
1477   *
1478   *  List<CountedValue<Order.Status>> orderStatusCount =
1479   *
1480   *     DB.find(Order.class)
1481   *      .select("status")
1482   *      .where()
1483   *      .gt("orderDate", LocalDate.now().minusMonths(3))
1484   *
1485   *      // fetch as single attribute with a COUNT
1486   *      .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
1487   *      .findSingleAttributeList();
1488   *
1489   *     for (CountedValue<Order.Status> entry : orderStatusCount) {
1490   *       System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
1491   *     }
1492   *
1493   *   // produces
1494   *
1495   *   count:3 orderStatus:NEW
1496   *   count:1 orderStatus:SHIPPED
1497   *   count:1 orderStatus:COMPLETE
1498   *
1499   * }</pre>
1500   */
1501  Query<T> setCountDistinct(CountDistinctOrder orderBy);
1502
1503  /**
1504   * Return the first row value.
1505   */
1506  int getFirstRow();
1507
1508  /**
1509   * Set the first row to return for this query.
1510   *
1511   * @param firstRow the first row to include in the query result.
1512   */
1513  Query<T> setFirstRow(int firstRow);
1514
1515  /**
1516   * Return the max rows for this query.
1517   */
1518  int getMaxRows();
1519
1520  /**
1521   * Set the maximum number of rows to return in the query.
1522   *
1523   * @param maxRows the maximum number of rows to return in the query.
1524   */
1525  Query<T> setMaxRows(int maxRows);
1526
1527  /**
1528   * Set the property to use as keys for a map.
1529   * <p>
1530   * If no property is set then the id property is used.
1531   * </p>
1532   * <pre>{@code
1533   *
1534   * // Assuming sku is unique for products...
1535   *
1536   * Map<String,Product> productMap = DB.find(Product.class)
1537   *     .setMapKey("sku")  // sku map keys...
1538   *     .findMap();
1539   *
1540   * }</pre>
1541   *
1542   * @param mapKey the property to use as keys for a map.
1543   */
1544  Query<T> setMapKey(String mapKey);
1545
1546  /**
1547   * Set this to false to not use the bean cache.
1548   * <p>
1549   * This method is now superseded by {@link #setBeanCacheMode(CacheMode)}
1550   * which provides more explicit options controlled bean cache use.
1551   * </p>
1552   * <p>
1553   * This method is likely to be deprecated in the future with migration
1554   * over to setUseBeanCache().
1555   * </p>
1556   */
1557  default Query<T> setUseCache(boolean useCache) {
1558    return setBeanCacheMode(useCache ? CacheMode.ON : CacheMode.OFF);
1559  }
1560
1561  /**
1562   * Set the mode to use the bean cache when executing this query.
1563   * <p>
1564   * By default "find by id" and "find by natural key" will use the bean cache
1565   * when bean caching is enabled. Setting this to false means that the query
1566   * will not use the bean cache and instead hit the database.
1567   * </p>
1568   * <p>
1569   * By default findList() with natural keys will not use the bean cache. In that
1570   * case we need to explicitly use the bean cache.
1571   * </p>
1572   */
1573  Query<T> setBeanCacheMode(CacheMode beanCacheMode);
1574
1575  /**
1576   * Set the {@link CacheMode} to use the query for executing this query.
1577   */
1578  Query<T> setUseQueryCache(CacheMode queryCacheMode);
1579
1580  /**
1581   * Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>.
1582   */
1583  default Query<T> setUseQueryCache(boolean enabled) {
1584    return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
1585  }
1586
1587  /**
1588   * Set the profile location of this query. This is used to relate query execution metrics
1589   * back to a location like a specific line of code.
1590   */
1591  Query<T> setProfileLocation(ProfileLocation profileLocation);
1592
1593  /**
1594   * Set a label on the query.
1595   * <p>
1596   * This label can be used to help identify query performance metrics but we can also use
1597   * profile location enhancement on Finders so for some that would be a better option.
1598   * </p>
1599   */
1600  Query<T> setLabel(String label);
1601
1602  /**
1603   * Set to true if this query should execute against the doc store.
1604   * <p>
1605   * When setting this you may also consider disabling lazy loading.
1606   * </p>
1607   */
1608  Query<T> setUseDocStore(boolean useDocStore);
1609
1610  /**
1611   * When set to true when you want the returned beans to be read only.
1612   */
1613  Query<T> setReadOnly(boolean readOnly);
1614
1615  /**
1616   * Will be deprecated - migrate to use setBeanCacheMode(CacheMode.RECACHE).
1617   * <p>
1618   * When set to true all the beans from this query are loaded into the bean cache.
1619   */
1620  Query<T> setLoadBeanCache(boolean loadBeanCache);
1621
1622  /**
1623   * Set a timeout on this query.
1624   * <p>
1625   * This will typically result in a call to setQueryTimeout() on a
1626   * preparedStatement. If the timeout occurs an exception will be thrown - this
1627   * will be a SQLException wrapped up in a PersistenceException.
1628   * </p>
1629   *
1630   * @param secs the query timeout limit in seconds. Zero means there is no limit.
1631   */
1632  Query<T> setTimeout(int secs);
1633
1634  /**
1635   * A hint which for JDBC translates to the Statement.fetchSize().
1636   * <p>
1637   * Gives the JDBC driver a hint as to the number of rows that should be
1638   * fetched from the database when more rows are needed for ResultSet.
1639   * </p>
1640   * <p>
1641   * Note that internally findEach and findEachWhile will set the fetch size
1642   * if it has not already as these queries expect to process a lot of rows.
1643   * If we didn't then Postgres and MySql for example would eagerly pull back
1644   * all the row data and potentially consume a lot of memory in the process.
1645   * </p>
1646   * <p>
1647   * As findEach and findEachWhile automatically set the fetch size we don't have
1648   * to do so generally but we might still wish to for tuning a specific use case.
1649   * </p>
1650   */
1651  Query<T> setBufferFetchSizeHint(int fetchSize);
1652
1653  /**
1654   * Return the sql that was generated for executing this query.
1655   * <p>
1656   * This is only available after the query has been executed and provided only
1657   * for informational purposes.
1658   * </p>
1659   */
1660  String getGeneratedSql();
1661
1662  /**
1663   * Execute the query with the given lock type and WAIT.
1664   * <p>
1665   * Note that <code>forUpdate()</code> is the same as
1666   * <code>withLock(LockType.UPDATE)</code>.
1667   * <p>
1668   * Provides us with the ability to explicitly use Postgres
1669   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
1670   */
1671  Query<T> withLock(LockType lockType);
1672
1673  /**
1674   * Execute the query with the given lock type and lock wait.
1675   * <p>
1676   * Note that <code>forUpdateNoWait()</code> is the same as
1677   * <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
1678   * <p>
1679   * Provides us with the ability to explicitly use Postgres
1680   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
1681   */
1682  Query<T> withLock(LockType lockType, LockWait lockWait);
1683
1684  /**
1685   * Execute using "for update" clause which results in the DB locking the record.
1686   * <p>
1687   * The same as <code>withLock(LockType.UPDATE, LockWait.WAIT)</code>.
1688   */
1689  Query<T> forUpdate();
1690
1691  /**
1692   * Execute using "for update" clause with "no wait" option.
1693   * <p>
1694   * This is typically a Postgres and Oracle only option at this stage.
1695   * <p>
1696   * The same as <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
1697   */
1698  Query<T> forUpdateNoWait();
1699
1700  /**
1701   * Execute using "for update" clause with "skip locked" option.
1702   * <p>
1703   * This is typically a Postgres and Oracle only option at this stage.
1704   * <p>
1705   * The same as <code>withLock(LockType.UPDATE, LockWait.SKIPLOCKED)</code>.
1706   */
1707  Query<T> forUpdateSkipLocked();
1708
1709  /**
1710   * Return true if this query has forUpdate set.
1711   */
1712  boolean isForUpdate();
1713
1714  /**
1715   * Return the "for update" wait mode to use.
1716   */
1717  LockWait getForUpdateLockWait();
1718
1719  /**
1720   * Return the lock type (strength) to use with "for update".
1721   */
1722  LockType getForUpdateLockType();
1723
1724  /**
1725   * Set root table alias.
1726   */
1727  Query<T> alias(String alias);
1728
1729  /**
1730   * Set the base table to use for this query.
1731   * <p>
1732   * Typically this is used when a table has partitioning and we wish to specify a specific
1733   * partition/table to query against.
1734   * </p>
1735   * <pre>{@code
1736   *
1737   *   QOrder()
1738   *   .setBaseTable("order_2019_05")
1739   *   .status.equalTo(Status.NEW)
1740   *   .findList();
1741   *
1742   * }</pre>
1743   */
1744  Query<T> setBaseTable(String baseTable);
1745
1746  /**
1747   * Return the type of beans being queried.
1748   */
1749  Class<T> getBeanType();
1750
1751  /**
1752   * Restrict the query to only return subtypes of the given inherit type.
1753   *
1754   * <pre>{@code
1755   *
1756   *   List<Animal> animals =
1757   *     new QAnimal()
1758   *       .name.startsWith("Fluffy")
1759   *       .setInheritType(Cat.class)
1760   *       .findList();
1761   *
1762   * }</pre>
1763   *
1764   * @param type An inheritance subtype of the
1765   */
1766  Query<T> setInheritType(Class<? extends T> type);
1767
1768  /**
1769   * Returns the inherit type. This is normally the same as getBeanType() returns as long as no other type is set.
1770   */
1771  Class<? extends T> getInheritType();
1772
1773  /**
1774   * Return the type of query being executed.
1775   */
1776  QueryType getQueryType();
1777
1778  /**
1779   * Set true if you want to disable lazy loading.
1780   * <p>
1781   * That is, once the object graph is returned further lazy loading is disabled.
1782   * </p>
1783   */
1784  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
1785
1786  /**
1787   * Returns the set of properties or paths that are unknown (do not map to known properties or paths).
1788   * <p>
1789   * Validate the query checking the where and orderBy expression paths to confirm if
1790   * they represent valid properties or paths for the given bean type.
1791   * </p>
1792   */
1793  Set<String> validate();
1794
1795  /**
1796   * Controls, if paginated queries should always append an 'order by id' statement at the end to
1797   * guarantee a deterministic sort result. This may affect performance.
1798   * If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
1799   * this query provides a deterministic result.
1800   */
1801  Query<T> orderById(boolean orderById);
1802
1803}