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 Java8 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 the query using callbacks to a visitor to process the resulting
834   * beans one at a time.
835   * <p>
836   * Note that findEachWhile (and findEach and findIterate) uses a "per graph"
837   * persistence context scope and adjusts jdbc fetch buffer size for large
838   * queries. As such it is better to use findList for small queries.
839   * </p>
840   * <p>
841   * This method is functionally equivalent to findIterate() but instead of using an
842   * iterator uses the Predicate (SAM) interface which is better suited to use with Java8 closures.
843   * </p>
844   * <pre>{@code
845   *
846   *  DB.find(Customer.class)
847   *     .fetch("contacts", FetchConfig.ofQuery(2))
848   *     .where().eq("status", Status.NEW)
849   *     .order().asc("id")
850   *     .setMaxRows(2000)
851   *     .findEachWhile((Customer customer) -> {
852   *
853   *       // do something with customer
854   *       System.out.println("-- visit " + customer);
855   *
856   *       // return true to continue processing or false to stop
857   *       return (customer.getId() < 40);
858   *     });
859   *
860   * }</pre>
861   *
862   * @param consumer the consumer used to process the queried beans.
863   */
864  void findEachWhile(Predicate<T> consumer);
865
866  /**
867   * Execute the query returning the list of objects.
868   * <p>
869   * This query will execute against the Database that was used to create it.
870   * </p>
871   * <pre>{@code
872   *
873   * List<Customer> customers = DB.find(Customer.class)
874   *     .where().ilike("name", "rob%")
875   *     .findList();
876   *
877   * }</pre>
878   */
879  @Nonnull
880  List<T> findList();
881
882  /**
883   * Execute the query returning the set of objects.
884   * <p>
885   * This query will execute against the Database that was used to create it.
886   * </p>
887   * <pre>{@code
888   *
889   * Set<Customer> customers = DB.find(Customer.class)
890   *     .where().ilike("name", "rob%")
891   *     .findSet();
892   *
893   * }</pre>
894   */
895  @Nonnull
896  Set<T> findSet();
897
898  /**
899   * Execute the query returning a map of the objects.
900   * <p>
901   * This query will execute against the Database that was used to create it.
902   * </p>
903   * <p>
904   * You can use setMapKey() so specify the property values to be used as keys
905   * on the map. If one is not specified then the id property is used.
906   * </p>
907   * <pre>{@code
908   *
909   * Map<String, Product> map = DB.find(Product.class)
910   *     .setMapKey("sku")
911   *     .findMap();
912   *
913   * }</pre>
914   */
915  @Nonnull
916  <K> Map<K, T> findMap();
917
918  /**
919   * Execute the query returning a list of values for a single property.
920   * <p>
921   * <h3>Example 1:</h3>
922   * <pre>{@code
923   *
924   *  List<String> names =
925   *    DB.find(Customer.class)
926   *      .select("name")
927   *      .order().asc("name")
928   *      .findSingleAttributeList();
929   *
930   * }</pre>
931   * <p>
932   * <h3>Example 2:</h3>
933   * <pre>{@code
934   *
935   *  List<String> names =
936   *    DB.find(Customer.class)
937   *      .setDistinct(true)
938   *      .select("name")
939   *      .where().eq("status", Customer.Status.NEW)
940   *      .order().asc("name")
941   *      .setMaxRows(100)
942   *      .findSingleAttributeList();
943   *
944   * }</pre>
945   *
946   * @return the list of values for the selected property
947   */
948  @Nonnull
949  <A> List<A> findSingleAttributeList();
950
951  /**
952   * Execute a query returning a single value of a single property/column.
953   * <p>
954   * <pre>{@code
955   *
956   *  String name =
957   *    DB.find(Customer.class)
958   *      .select("name")
959   *      .where().eq("id", 42)
960   *      .findSingleAttribute();
961   *
962   * }</pre>
963   */
964  <A> A findSingleAttribute();
965
966  /**
967   * Return true if this is countDistinct query.
968   */
969  boolean isCountDistinct();
970
971  /**
972   * Execute the query returning true if a row is found.
973   * <p>
974   * The query is executed using max rows of 1 and will only select the id property.
975   * This method is really just a convenient way to optimise a query to perform a
976   * 'does a row exist in the db' check.
977   * </p>
978   *
979   * <h2>Example using a query bean:</h2>
980   * <pre>{@code
981   *
982   *   boolean userExists =
983   *     new QContact()
984   *       .email.equalTo("[email protected]")
985   *       .exists();
986   *
987   * }</pre>
988   *
989   * <h2>Example:</h2>
990   * <pre>{@code
991   *
992   *   boolean userExists = query()
993   *     .where().eq("email", "[email protected]")
994   *     .exists();
995   *
996   * }</pre>
997   *
998   * @return True if the query finds a matching row in the database
999   */
1000  boolean exists();
1001
1002  /**
1003   * Execute the query returning either a single bean or null (if no matching
1004   * bean is found).
1005   * <p>
1006   * If more than 1 row is found for this query then a NonUniqueResultException is
1007   * thrown.
1008   * </p>
1009   * <p>
1010   * This is useful when your predicates dictate that your query should only
1011   * return 0 or 1 results.
1012   * </p>
1013   * <pre>{@code
1014   *
1015   * // assuming the sku of products is unique...
1016   * Product product = DB.find(Product.class)
1017   *         .where().eq("sku", "aa113")
1018   *         .findOne();
1019   * ...
1020   * }</pre>
1021   * <p>
1022   * It is also useful with finding objects by their id when you want to specify
1023   * further join information.
1024   * </p>
1025   * <pre>{@code
1026   *
1027   * // Fetch order 1 and additionally fetch join its order details...
1028   * Order order = DB.find(Order.class)
1029   *       .setId(1)
1030   *       .fetch("details")
1031   *       .findOne();
1032   *
1033   * // the order details were eagerly loaded
1034   * List<OrderDetail> details = order.getDetails();
1035   * ...
1036   * }</pre>
1037   *
1038   * @throws NonUniqueResultException if more than one result was found
1039   */
1040  @Nullable
1041  T findOne();
1042
1043  /**
1044   * Execute the query returning an optional bean.
1045   */
1046  @Nonnull
1047  Optional<T> findOneOrEmpty();
1048
1049  /**
1050   * Return versions of a @History entity bean.
1051   * <p>
1052   * Note that this query will work against view based history implementations
1053   * but not sql2011 standards based implementations that require a start and
1054   * end timestamp to be specified.
1055   * </p>
1056   * <p>
1057   * Generally this query is expected to be a find by id or unique predicates query.
1058   * It will execute the query against the history returning the versions of the bean.
1059   * </p>
1060   */
1061  @Nonnull
1062  List<Version<T>> findVersions();
1063
1064  /**
1065   * Return versions of a @History entity bean between the 2 timestamps.
1066   * <p>
1067   * Generally this query is expected to be a find by id or unique predicates query.
1068   * It will execute the query against the history returning the versions of the bean.
1069   * </p>
1070   */
1071  @Nonnull
1072  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
1073
1074  /**
1075   * Execute as a delete query deleting the 'root level' beans that match the predicates
1076   * in the query.
1077   * <p>
1078   * Note that if the query includes joins then the generated delete statement may not be
1079   * optimal depending on the database platform.
1080   * </p>
1081   *
1082   * @return the number of beans/rows that were deleted.
1083   */
1084  int delete();
1085
1086  /**
1087   * Execute as a delete query returning the number of rows deleted using the given transaction.
1088   * <p>
1089   * Note that if the query includes joins then the generated delete statement may not be
1090   * optimal depending on the database platform.
1091   * </p>
1092   *
1093   * @return the number of beans/rows that were deleted.
1094   */
1095  int delete(Transaction transaction);
1096
1097  /**
1098   * Execute the UpdateQuery returning the number of rows updated.
1099   *
1100   * @return the number of beans/rows updated.
1101   */
1102  int update();
1103
1104  /**
1105   * Execute the UpdateQuery returning the number of rows updated using the given transaction.
1106   *
1107   * @return the number of beans/rows updated.
1108   */
1109  int update(Transaction transaction);
1110
1111  /**
1112   * Return the count of entities this query should return.
1113   * <p>
1114   * This is the number of 'top level' or 'root level' entities.
1115   * </p>
1116   */
1117  int findCount();
1118
1119  /**
1120   * Execute find row count query in a background thread.
1121   * <p>
1122   * This returns a Future object which can be used to cancel, check the
1123   * execution status (isDone etc) and get the value (with or without a
1124   * timeout).
1125   * </p>
1126   *
1127   * @return a Future object for the row count query
1128   */
1129  @Nonnull
1130  FutureRowCount<T> findFutureCount();
1131
1132  /**
1133   * Execute find Id's query in a background thread.
1134   * <p>
1135   * This returns a Future object which can be used to cancel, check the
1136   * execution status (isDone etc) and get the value (with or without a
1137   * timeout).
1138   * </p>
1139   *
1140   * @return a Future object for the list of Id's
1141   */
1142  @Nonnull
1143  FutureIds<T> findFutureIds();
1144
1145  /**
1146   * Execute find list query in a background thread.
1147   * <p>
1148   * This query will execute in it's own PersistenceContext and using its own transaction.
1149   * What that means is that it will not share any bean instances with other queries.
1150   * </p>
1151   *
1152   * @return a Future object for the list result of the query
1153   */
1154  @Nonnull
1155  FutureList<T> findFutureList();
1156
1157  /**
1158   * Return a PagedList for this query using firstRow and maxRows.
1159   * <p>
1160   * The benefit of using this over findList() is that it provides functionality to get the
1161   * total row count etc.
1162   * </p>
1163   * <p>
1164   * If maxRows is not set on the query prior to calling findPagedList() then a
1165   * PersistenceException is thrown.
1166   * </p>
1167   * <pre>{@code
1168   *
1169   *  PagedList<Order> pagedList = DB.find(Order.class)
1170   *       .setFirstRow(50)
1171   *       .setMaxRows(20)
1172   *       .findPagedList();
1173   *
1174   *       // fetch the total row count in the background
1175   *       pagedList.loadRowCount();
1176   *
1177   *       List<Order> orders = pagedList.getList();
1178   *       int totalRowCount = pagedList.getTotalRowCount();
1179   *
1180   * }</pre>
1181   *
1182   * @return The PagedList
1183   */
1184  @Nonnull
1185  PagedList<T> findPagedList();
1186
1187  /**
1188   * Set a named bind parameter. Named parameters have a colon to prefix the name.
1189   * <pre>{@code
1190   *
1191   * // a query with a named parameter
1192   * String oql = "find order where status = :orderStatus";
1193   *
1194   * List<Order> list = DB.find(Order.class, oql)
1195   *   .setParameter("orderStatus", OrderStatus.NEW)
1196   *   .findList();
1197   *
1198   * }</pre>
1199   *
1200   * @param name  the parameter name
1201   * @param value the parameter value
1202   */
1203  Query<T> setParameter(String name, Object value);
1204
1205  /**
1206   * Set an ordered bind parameter according to its position. Note that the
1207   * position starts at 1 to be consistent with JDBC PreparedStatement. You need
1208   * to set a parameter value for each ? you have in the query.
1209   * <pre>{@code
1210   *
1211   * // a query with a positioned parameter
1212   * String oql = "where status = ? order by id desc";
1213   *
1214   * List<Order> list = DB.createQuery(Order.class, oql)
1215   *   .setParameter(1, OrderStatus.NEW)
1216   *   .findList();
1217   *
1218   * }</pre>
1219   *
1220   * @param position the parameter bind position starting from 1 (not 0)
1221   * @param value    the parameter bind value.
1222   */
1223  Query<T> setParameter(int position, Object value);
1224
1225  /**
1226   * Bind the next positioned parameter.
1227   *
1228   * <pre>{@code
1229   *
1230   * // a query with a positioned parameters
1231   * String oql = "where status = ? and name = ?";
1232   *
1233   * List<Order> list = DB.createQuery(Order.class, oql)
1234   *   .setParameter(OrderStatus.NEW)
1235   *   .setParameter("Rob")
1236   *   .findList();
1237   *
1238   * }</pre>
1239   */
1240  Query<T> setParameter(Object value);
1241
1242  /**
1243   * Bind all the positioned parameters.
1244   * <p>
1245   * A convenience for multiple calls to {@link #setParameter(Object)}
1246   */
1247  Query<T> setParameters(Object... values);
1248
1249  /**
1250   * Set the Id value to query. This is used with findOne().
1251   * <p>
1252   * You can use this to have further control over the query. For example adding
1253   * fetch joins.
1254   * </p>
1255   * <pre>{@code
1256   *
1257   * Order order = DB.find(Order.class)
1258   *     .setId(1)
1259   *     .fetch("details")
1260   *     .findOne();
1261   *
1262   * // the order details were eagerly fetched
1263   * List<OrderDetail> details = order.getDetails();
1264   *
1265   * }</pre>
1266   */
1267  Query<T> setId(Object id);
1268
1269  /**
1270   * Return the Id value.
1271   */
1272  Object getId();
1273
1274  /**
1275   * Add a single Expression to the where clause returning the query.
1276   * <pre>{@code
1277   *
1278   * List<Order> newOrders = DB.find(Order.class)
1279   *            .where().eq("status", Order.NEW)
1280   *            .findList();
1281   * ...
1282   *
1283   * }</pre>
1284   */
1285  Query<T> where(Expression expression);
1286
1287  /**
1288   * Add Expressions to the where clause with the ability to chain on the
1289   * ExpressionList. You can use this for adding multiple expressions to the
1290   * where clause.
1291   * <pre>{@code
1292   *
1293   * List<Order> orders = DB.find(Order.class)
1294   *     .where()
1295   *       .eq("status", Order.NEW)
1296   *       .ilike("customer.name","rob%")
1297   *     .findList();
1298   *
1299   * }</pre>
1300   *
1301   * @return The ExpressionList for adding expressions to.
1302   * @see Expr
1303   */
1304  ExpressionList<T> where();
1305
1306  /**
1307   * Add Full text search expressions for Document store queries.
1308   * <p>
1309   * This is currently ElasticSearch only and provides the full text
1310   * expressions such as Match and Multi-Match.
1311   * </p>
1312   * <p>
1313   * This automatically makes this query a "Doc Store" query and will execute
1314   * against the document store (ElasticSearch).
1315   * </p>
1316   * <p>
1317   * Expressions added here are added to the "query" section of an ElasticSearch
1318   * query rather than the "filter" section.
1319   * </p>
1320   * <p>
1321   * Expressions added to the where() are added to the "filter" section of an
1322   * ElasticSearch query.
1323   * </p>
1324   */
1325  ExpressionList<T> text();
1326
1327  /**
1328   * This applies a filter on the 'many' property list rather than the root
1329   * level objects.
1330   * <p>
1331   * Typically you will use this in a scenario where the cardinality is high on
1332   * the 'many' property you wish to join to. Say you want to fetch customers
1333   * and their associated orders... but instead of getting all the orders for
1334   * each customer you only want to get the new orders they placed since last
1335   * week. In this case you can use filterMany() to filter the orders.
1336   * </p>
1337   * <pre>{@code
1338   *
1339   * List<Customer> list = DB.find(Customer.class)
1340   *     .fetch("orders")
1341   *     .where().ilike("name", "rob%")
1342   *     .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek)
1343   *     .findList();
1344   *
1345   * }</pre>
1346   * <p>
1347   * Please note you have to be careful that you add expressions to the correct
1348   * expression list - as there is one for the 'root level' and one for each
1349   * filterMany that you have.
1350   * </p>
1351   *
1352   * @param propertyName the name of the many property that you want to have a filter on.
1353   * @return the expression list that you add filter expressions for the many to.
1354   */
1355  ExpressionList<T> filterMany(String propertyName);
1356
1357  /**
1358   * Add Expressions to the Having clause return the ExpressionList.
1359   * <p>
1360   * Currently only beans based on raw sql will use the having clause.
1361   * </p>
1362   * <p>
1363   * Note that this returns the ExpressionList (so you can add multiple
1364   * expressions to the query in a fluent API way).
1365   * </p>
1366   *
1367   * @return The ExpressionList for adding more expressions to.
1368   * @see Expr
1369   */
1370  ExpressionList<T> having();
1371
1372  /**
1373   * Add an expression to the having clause returning the query.
1374   * <p>
1375   * Currently only beans based on raw sql will use the having clause.
1376   * </p>
1377   * <p>
1378   * This is similar to {@link #having()} except it returns the query rather
1379   * than the ExpressionList. This is useful when you want to further specify
1380   * something on the query.
1381   * </p>
1382   *
1383   * @param addExpressionToHaving the expression to add to the having clause.
1384   * @return the Query object
1385   */
1386  Query<T> having(Expression addExpressionToHaving);
1387
1388  /**
1389   * Set the order by clause replacing the existing order by clause if there is
1390   * one.
1391   * <p>
1392   * This follows SQL syntax using commas between each property with the
1393   * optional asc and desc keywords representing ascending and descending order
1394   * respectively.
1395   */
1396  Query<T> orderBy(String orderByClause);
1397
1398  /**
1399   * Set the order by clause replacing the existing order by clause if there is
1400   * one.
1401   * <p>
1402   * This follows SQL syntax using commas between each property with the
1403   * optional asc and desc keywords representing ascending and descending order
1404   * respectively.
1405   */
1406  Query<T> order(String orderByClause);
1407
1408  /**
1409   * Return the OrderBy so that you can append an ascending or descending
1410   * property to the order by clause.
1411   * <p>
1412   * This will never return a null. If no order by clause exists then an 'empty'
1413   * OrderBy object is returned.
1414   * <p>
1415   * This is the same as <code>orderBy()</code>
1416   */
1417  OrderBy<T> order();
1418
1419  /**
1420   * Return the OrderBy so that you can append an ascending or descending
1421   * property to the order by clause.
1422   * <p>
1423   * This will never return a null. If no order by clause exists then an 'empty'
1424   * OrderBy object is returned.
1425   * <p>
1426   * This is the same as <code>order()</code>
1427   */
1428  OrderBy<T> orderBy();
1429
1430  /**
1431   * Set an OrderBy object to replace any existing OrderBy clause.
1432   */
1433  Query<T> setOrder(OrderBy<T> orderBy);
1434
1435  /**
1436   * Set an OrderBy object to replace any existing OrderBy clause.
1437   */
1438  Query<T> setOrderBy(OrderBy<T> orderBy);
1439
1440  /**
1441   * Set whether this query uses DISTINCT.
1442   * <p>
1443   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
1444   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
1445   * </p>
1446   * <pre>{@code
1447   *
1448   *   List<Customer> customers =
1449   *       DB.find(Customer.class)
1450   *          .setDistinct(true)
1451   *          .select("name")
1452   *          .findList();
1453   *
1454   * }</pre>
1455   */
1456  Query<T> setDistinct(boolean isDistinct);
1457
1458  /**
1459   * Extended version for setDistinct in conjunction with "findSingleAttributeList";
1460   *
1461   * <pre>{@code
1462   *
1463   *  List<CountedValue<Order.Status>> orderStatusCount =
1464   *
1465   *     DB.find(Order.class)
1466   *      .select("status")
1467   *      .where()
1468   *      .gt("orderDate", LocalDate.now().minusMonths(3))
1469   *
1470   *      // fetch as single attribute with a COUNT
1471   *      .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
1472   *      .findSingleAttributeList();
1473   *
1474   *     for (CountedValue<Order.Status> entry : orderStatusCount) {
1475   *       System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
1476   *     }
1477   *
1478   *   // produces
1479   *
1480   *   count:3 orderStatus:NEW
1481   *   count:1 orderStatus:SHIPPED
1482   *   count:1 orderStatus:COMPLETE
1483   *
1484   * }</pre>
1485   */
1486  Query<T> setCountDistinct(CountDistinctOrder orderBy);
1487
1488  /**
1489   * Return the first row value.
1490   */
1491  int getFirstRow();
1492
1493  /**
1494   * Set the first row to return for this query.
1495   *
1496   * @param firstRow the first row to include in the query result.
1497   */
1498  Query<T> setFirstRow(int firstRow);
1499
1500  /**
1501   * Return the max rows for this query.
1502   */
1503  int getMaxRows();
1504
1505  /**
1506   * Set the maximum number of rows to return in the query.
1507   *
1508   * @param maxRows the maximum number of rows to return in the query.
1509   */
1510  Query<T> setMaxRows(int maxRows);
1511
1512  /**
1513   * Set the property to use as keys for a map.
1514   * <p>
1515   * If no property is set then the id property is used.
1516   * </p>
1517   * <pre>{@code
1518   *
1519   * // Assuming sku is unique for products...
1520   *
1521   * Map<String,Product> productMap = DB.find(Product.class)
1522   *     .setMapKey("sku")  // sku map keys...
1523   *     .findMap();
1524   *
1525   * }</pre>
1526   *
1527   * @param mapKey the property to use as keys for a map.
1528   */
1529  Query<T> setMapKey(String mapKey);
1530
1531  /**
1532   * Set this to false to not use the bean cache.
1533   * <p>
1534   * This method is now superseded by {@link #setBeanCacheMode(CacheMode)}
1535   * which provides more explicit options controlled bean cache use.
1536   * </p>
1537   * <p>
1538   * This method is likely to be deprecated in the future with migration
1539   * over to setUseBeanCache().
1540   * </p>
1541   */
1542  default Query<T> setUseCache(boolean useCache) {
1543    return setBeanCacheMode(useCache ? CacheMode.ON : CacheMode.OFF);
1544  }
1545
1546  /**
1547   * Set the mode to use the bean cache when executing this query.
1548   * <p>
1549   * By default "find by id" and "find by natural key" will use the bean cache
1550   * when bean caching is enabled. Setting this to false means that the query
1551   * will not use the bean cache and instead hit the database.
1552   * </p>
1553   * <p>
1554   * By default findList() with natural keys will not use the bean cache. In that
1555   * case we need to explicitly use the bean cache.
1556   * </p>
1557   */
1558  Query<T> setBeanCacheMode(CacheMode beanCacheMode);
1559
1560  /**
1561   * Set the {@link CacheMode} to use the query for executing this query.
1562   */
1563  Query<T> setUseQueryCache(CacheMode queryCacheMode);
1564
1565  /**
1566   * Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>.
1567   */
1568  default Query<T> setUseQueryCache(boolean enabled) {
1569    return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
1570  }
1571
1572  /**
1573   * Set the profile location of this query. This is used to relate query execution metrics
1574   * back to a location like a specific line of code.
1575   */
1576  Query<T> setProfileLocation(ProfileLocation profileLocation);
1577
1578  /**
1579   * Set a label on the query.
1580   * <p>
1581   * This label can be used to help identify query performance metrics but we can also use
1582   * profile location enhancement on Finders so for some that would be a better option.
1583   * </p>
1584   */
1585  Query<T> setLabel(String label);
1586
1587  /**
1588   * Set to true if this query should execute against the doc store.
1589   * <p>
1590   * When setting this you may also consider disabling lazy loading.
1591   * </p>
1592   */
1593  Query<T> setUseDocStore(boolean useDocStore);
1594
1595  /**
1596   * When set to true when you want the returned beans to be read only.
1597   */
1598  Query<T> setReadOnly(boolean readOnly);
1599
1600  /**
1601   * Will be deprecated - migrate to use setBeanCacheMode(CacheMode.RECACHE).
1602   * <p>
1603   * When set to true all the beans from this query are loaded into the bean cache.
1604   */
1605  Query<T> setLoadBeanCache(boolean loadBeanCache);
1606
1607  /**
1608   * Set a timeout on this query.
1609   * <p>
1610   * This will typically result in a call to setQueryTimeout() on a
1611   * preparedStatement. If the timeout occurs an exception will be thrown - this
1612   * will be a SQLException wrapped up in a PersistenceException.
1613   * </p>
1614   *
1615   * @param secs the query timeout limit in seconds. Zero means there is no limit.
1616   */
1617  Query<T> setTimeout(int secs);
1618
1619  /**
1620   * A hint which for JDBC translates to the Statement.fetchSize().
1621   * <p>
1622   * Gives the JDBC driver a hint as to the number of rows that should be
1623   * fetched from the database when more rows are needed for ResultSet.
1624   * </p>
1625   * <p>
1626   * Note that internally findEach and findEachWhile will set the fetch size
1627   * if it has not already as these queries expect to process a lot of rows.
1628   * If we didn't then Postgres and MySql for example would eagerly pull back
1629   * all the row data and potentially consume a lot of memory in the process.
1630   * </p>
1631   * <p>
1632   * As findEach and findEachWhile automatically set the fetch size we don't have
1633   * to do so generally but we might still wish to for tuning a specific use case.
1634   * </p>
1635   */
1636  Query<T> setBufferFetchSizeHint(int fetchSize);
1637
1638  /**
1639   * Return the sql that was generated for executing this query.
1640   * <p>
1641   * This is only available after the query has been executed and provided only
1642   * for informational purposes.
1643   * </p>
1644   */
1645  String getGeneratedSql();
1646
1647  /**
1648   * Execute the query with the given lock type and WAIT.
1649   * <p>
1650   * Note that <code>forUpdate()</code> is the same as
1651   * <code>withLock(LockType.UPDATE)</code>.
1652   * <p>
1653   * Provides us with the ability to explicitly use Postgres
1654   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
1655   */
1656  Query<T> withLock(LockType lockType);
1657
1658  /**
1659   * Execute the query with the given lock type and lock wait.
1660   * <p>
1661   * Note that <code>forUpdateNoWait()</code> is the same as
1662   * <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
1663   * <p>
1664   * Provides us with the ability to explicitly use Postgres
1665   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
1666   */
1667  Query<T> withLock(LockType lockType, LockWait lockWait);
1668
1669  /**
1670   * Execute using "for update" clause which results in the DB locking the record.
1671   * <p>
1672   * The same as <code>withLock(LockType.UPDATE, LockWait.WAIT)</code>.
1673   */
1674  Query<T> forUpdate();
1675
1676  /**
1677   * Execute using "for update" clause with "no wait" option.
1678   * <p>
1679   * This is typically a Postgres and Oracle only option at this stage.
1680   * <p>
1681   * The same as <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
1682   */
1683  Query<T> forUpdateNoWait();
1684
1685  /**
1686   * Execute using "for update" clause with "skip locked" option.
1687   * <p>
1688   * This is typically a Postgres and Oracle only option at this stage.
1689   * <p>
1690   * The same as <code>withLock(LockType.UPDATE, LockWait.SKIPLOCKED)</code>.
1691   */
1692  Query<T> forUpdateSkipLocked();
1693
1694  /**
1695   * Return true if this query has forUpdate set.
1696   */
1697  boolean isForUpdate();
1698
1699  /**
1700   * Return the "for update" wait mode to use.
1701   */
1702  LockWait getForUpdateLockWait();
1703
1704  /**
1705   * Return the lock type (strength) to use with "for update".
1706   */
1707  LockType getForUpdateLockType();
1708
1709  /**
1710   * Set root table alias.
1711   */
1712  Query<T> alias(String alias);
1713
1714  /**
1715   * Set the base table to use for this query.
1716   * <p>
1717   * Typically this is used when a table has partitioning and we wish to specify a specific
1718   * partition/table to query against.
1719   * </p>
1720   * <pre>{@code
1721   *
1722   *   QOrder()
1723   *   .setBaseTable("order_2019_05")
1724   *   .status.equalTo(Status.NEW)
1725   *   .findList();
1726   *
1727   * }</pre>
1728   */
1729  Query<T> setBaseTable(String baseTable);
1730
1731  /**
1732   * Return the type of beans being queried.
1733   */
1734  Class<T> getBeanType();
1735
1736  /**
1737   * Restrict the query to only return subtypes of the given inherit type.
1738   *
1739   * <pre>{@code
1740   *
1741   *   List<Animal> animals =
1742   *     new QAnimal()
1743   *       .name.startsWith("Fluffy")
1744   *       .setInheritType(Cat.class)
1745   *       .findList();
1746   *
1747   * }</pre>
1748   *
1749   * @param type An inheritance subtype of the
1750   */
1751  Query<T> setInheritType(Class<? extends T> type);
1752
1753  /**
1754   * Returns the inherit type. This is normally the same as getBeanType() returns as long as no other type is set.
1755   */
1756  Class<? extends T> getInheritType();
1757
1758  /**
1759   * Return the type of query being executed.
1760   */
1761  QueryType getQueryType();
1762
1763  /**
1764   * Set true if you want to disable lazy loading.
1765   * <p>
1766   * That is, once the object graph is returned further lazy loading is disabled.
1767   * </p>
1768   */
1769  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
1770
1771  /**
1772   * Returns the set of properties or paths that are unknown (do not map to known properties or paths).
1773   * <p>
1774   * Validate the query checking the where and orderBy expression paths to confirm if
1775   * they represent valid properties or paths for the given bean type.
1776   * </p>
1777   */
1778  Set<String> validate();
1779
1780  /**
1781   * Controls, if paginated queries should always append an 'order by id' statement at the end to
1782   * guarantee a deterministic sort result. This may affect performance.
1783   * If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
1784   * this query provides a deterministic result.
1785   */
1786  Query<T> orderById(boolean orderById);
1787
1788}