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