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