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