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