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