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 Java8 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 the query using callbacks to a visitor to process the resulting 834 * beans one at a time. 835 * <p> 836 * Note that findEachWhile (and findEach and findIterate) uses a "per graph" 837 * persistence context scope and adjusts jdbc fetch buffer size for large 838 * queries. As such it is better to use findList for small queries. 839 * </p> 840 * <p> 841 * This method is functionally equivalent to findIterate() but instead of using an 842 * iterator uses the Predicate (SAM) interface which is better suited to use with Java8 closures. 843 * </p> 844 * <pre>{@code 845 * 846 * DB.find(Customer.class) 847 * .fetch("contacts", FetchConfig.ofQuery(2)) 848 * .where().eq("status", Status.NEW) 849 * .order().asc("id") 850 * .setMaxRows(2000) 851 * .findEachWhile((Customer customer) -> { 852 * 853 * // do something with customer 854 * System.out.println("-- visit " + customer); 855 * 856 * // return true to continue processing or false to stop 857 * return (customer.getId() < 40); 858 * }); 859 * 860 * }</pre> 861 * 862 * @param consumer the consumer used to process the queried beans. 863 */ 864 void findEachWhile(Predicate<T> consumer); 865 866 /** 867 * Execute the query returning the list of objects. 868 * <p> 869 * This query will execute against the Database that was used to create it. 870 * </p> 871 * <pre>{@code 872 * 873 * List<Customer> customers = DB.find(Customer.class) 874 * .where().ilike("name", "rob%") 875 * .findList(); 876 * 877 * }</pre> 878 */ 879 @Nonnull 880 List<T> findList(); 881 882 /** 883 * Execute the query returning the set of objects. 884 * <p> 885 * This query will execute against the Database that was used to create it. 886 * </p> 887 * <pre>{@code 888 * 889 * Set<Customer> customers = DB.find(Customer.class) 890 * .where().ilike("name", "rob%") 891 * .findSet(); 892 * 893 * }</pre> 894 */ 895 @Nonnull 896 Set<T> findSet(); 897 898 /** 899 * Execute the query returning a map of the objects. 900 * <p> 901 * This query will execute against the Database that was used to create it. 902 * </p> 903 * <p> 904 * You can use setMapKey() so specify the property values to be used as keys 905 * on the map. If one is not specified then the id property is used. 906 * </p> 907 * <pre>{@code 908 * 909 * Map<String, Product> map = DB.find(Product.class) 910 * .setMapKey("sku") 911 * .findMap(); 912 * 913 * }</pre> 914 */ 915 @Nonnull 916 <K> Map<K, T> findMap(); 917 918 /** 919 * Execute the query returning a list of values for a single property. 920 * <p> 921 * <h3>Example 1:</h3> 922 * <pre>{@code 923 * 924 * List<String> names = 925 * DB.find(Customer.class) 926 * .select("name") 927 * .order().asc("name") 928 * .findSingleAttributeList(); 929 * 930 * }</pre> 931 * <p> 932 * <h3>Example 2:</h3> 933 * <pre>{@code 934 * 935 * List<String> names = 936 * DB.find(Customer.class) 937 * .setDistinct(true) 938 * .select("name") 939 * .where().eq("status", Customer.Status.NEW) 940 * .order().asc("name") 941 * .setMaxRows(100) 942 * .findSingleAttributeList(); 943 * 944 * }</pre> 945 * 946 * @return the list of values for the selected property 947 */ 948 @Nonnull 949 <A> List<A> findSingleAttributeList(); 950 951 /** 952 * Execute a query returning a single value of a single property/column. 953 * <p> 954 * <pre>{@code 955 * 956 * String name = 957 * DB.find(Customer.class) 958 * .select("name") 959 * .where().eq("id", 42) 960 * .findSingleAttribute(); 961 * 962 * }</pre> 963 */ 964 <A> A findSingleAttribute(); 965 966 /** 967 * Return true if this is countDistinct query. 968 */ 969 boolean isCountDistinct(); 970 971 /** 972 * Execute the query returning true if a row is found. 973 * <p> 974 * The query is executed using max rows of 1 and will only select the id property. 975 * This method is really just a convenient way to optimise a query to perform a 976 * 'does a row exist in the db' check. 977 * </p> 978 * 979 * <h2>Example using a query bean:</h2> 980 * <pre>{@code 981 * 982 * boolean userExists = 983 * new QContact() 984 * .email.equalTo("[email protected]") 985 * .exists(); 986 * 987 * }</pre> 988 * 989 * <h2>Example:</h2> 990 * <pre>{@code 991 * 992 * boolean userExists = query() 993 * .where().eq("email", "[email protected]") 994 * .exists(); 995 * 996 * }</pre> 997 * 998 * @return True if the query finds a matching row in the database 999 */ 1000 boolean exists(); 1001 1002 /** 1003 * Execute the query returning either a single bean or null (if no matching 1004 * bean is found). 1005 * <p> 1006 * If more than 1 row is found for this query then a NonUniqueResultException is 1007 * thrown. 1008 * </p> 1009 * <p> 1010 * This is useful when your predicates dictate that your query should only 1011 * return 0 or 1 results. 1012 * </p> 1013 * <pre>{@code 1014 * 1015 * // assuming the sku of products is unique... 1016 * Product product = DB.find(Product.class) 1017 * .where().eq("sku", "aa113") 1018 * .findOne(); 1019 * ... 1020 * }</pre> 1021 * <p> 1022 * It is also useful with finding objects by their id when you want to specify 1023 * further join information. 1024 * </p> 1025 * <pre>{@code 1026 * 1027 * // Fetch order 1 and additionally fetch join its order details... 1028 * Order order = DB.find(Order.class) 1029 * .setId(1) 1030 * .fetch("details") 1031 * .findOne(); 1032 * 1033 * // the order details were eagerly loaded 1034 * List<OrderDetail> details = order.getDetails(); 1035 * ... 1036 * }</pre> 1037 * 1038 * @throws NonUniqueResultException if more than one result was found 1039 */ 1040 @Nullable 1041 T findOne(); 1042 1043 /** 1044 * Execute the query returning an optional bean. 1045 */ 1046 @Nonnull 1047 Optional<T> findOneOrEmpty(); 1048 1049 /** 1050 * Return versions of a @History entity bean. 1051 * <p> 1052 * Note that this query will work against view based history implementations 1053 * but not sql2011 standards based implementations that require a start and 1054 * end timestamp to be specified. 1055 * </p> 1056 * <p> 1057 * Generally this query is expected to be a find by id or unique predicates query. 1058 * It will execute the query against the history returning the versions of the bean. 1059 * </p> 1060 */ 1061 @Nonnull 1062 List<Version<T>> findVersions(); 1063 1064 /** 1065 * Return versions of a @History entity bean between the 2 timestamps. 1066 * <p> 1067 * Generally this query is expected to be a find by id or unique predicates query. 1068 * It will execute the query against the history returning the versions of the bean. 1069 * </p> 1070 */ 1071 @Nonnull 1072 List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end); 1073 1074 /** 1075 * Execute as a delete query deleting the 'root level' beans that match the predicates 1076 * in the query. 1077 * <p> 1078 * Note that if the query includes joins then the generated delete statement may not be 1079 * optimal depending on the database platform. 1080 * </p> 1081 * 1082 * @return the number of beans/rows that were deleted. 1083 */ 1084 int delete(); 1085 1086 /** 1087 * Execute as a delete query returning the number of rows deleted using the given transaction. 1088 * <p> 1089 * Note that if the query includes joins then the generated delete statement may not be 1090 * optimal depending on the database platform. 1091 * </p> 1092 * 1093 * @return the number of beans/rows that were deleted. 1094 */ 1095 int delete(Transaction transaction); 1096 1097 /** 1098 * Execute the UpdateQuery returning the number of rows updated. 1099 * 1100 * @return the number of beans/rows updated. 1101 */ 1102 int update(); 1103 1104 /** 1105 * Execute the UpdateQuery returning the number of rows updated using the given transaction. 1106 * 1107 * @return the number of beans/rows updated. 1108 */ 1109 int update(Transaction transaction); 1110 1111 /** 1112 * Return the count of entities this query should return. 1113 * <p> 1114 * This is the number of 'top level' or 'root level' entities. 1115 * </p> 1116 */ 1117 int findCount(); 1118 1119 /** 1120 * Execute find row count query in a background thread. 1121 * <p> 1122 * This returns a Future object which can be used to cancel, check the 1123 * execution status (isDone etc) and get the value (with or without a 1124 * timeout). 1125 * </p> 1126 * 1127 * @return a Future object for the row count query 1128 */ 1129 @Nonnull 1130 FutureRowCount<T> findFutureCount(); 1131 1132 /** 1133 * Execute find Id's query in a background thread. 1134 * <p> 1135 * This returns a Future object which can be used to cancel, check the 1136 * execution status (isDone etc) and get the value (with or without a 1137 * timeout). 1138 * </p> 1139 * 1140 * @return a Future object for the list of Id's 1141 */ 1142 @Nonnull 1143 FutureIds<T> findFutureIds(); 1144 1145 /** 1146 * Execute find list query in a background thread. 1147 * <p> 1148 * This query will execute in it's own PersistenceContext and using its own transaction. 1149 * What that means is that it will not share any bean instances with other queries. 1150 * </p> 1151 * 1152 * @return a Future object for the list result of the query 1153 */ 1154 @Nonnull 1155 FutureList<T> findFutureList(); 1156 1157 /** 1158 * Return a PagedList for this query using firstRow and maxRows. 1159 * <p> 1160 * The benefit of using this over findList() is that it provides functionality to get the 1161 * total row count etc. 1162 * </p> 1163 * <p> 1164 * If maxRows is not set on the query prior to calling findPagedList() then a 1165 * PersistenceException is thrown. 1166 * </p> 1167 * <pre>{@code 1168 * 1169 * PagedList<Order> pagedList = DB.find(Order.class) 1170 * .setFirstRow(50) 1171 * .setMaxRows(20) 1172 * .findPagedList(); 1173 * 1174 * // fetch the total row count in the background 1175 * pagedList.loadRowCount(); 1176 * 1177 * List<Order> orders = pagedList.getList(); 1178 * int totalRowCount = pagedList.getTotalRowCount(); 1179 * 1180 * }</pre> 1181 * 1182 * @return The PagedList 1183 */ 1184 @Nonnull 1185 PagedList<T> findPagedList(); 1186 1187 /** 1188 * Set a named bind parameter. Named parameters have a colon to prefix the name. 1189 * <pre>{@code 1190 * 1191 * // a query with a named parameter 1192 * String oql = "find order where status = :orderStatus"; 1193 * 1194 * List<Order> list = DB.find(Order.class, oql) 1195 * .setParameter("orderStatus", OrderStatus.NEW) 1196 * .findList(); 1197 * 1198 * }</pre> 1199 * 1200 * @param name the parameter name 1201 * @param value the parameter value 1202 */ 1203 Query<T> setParameter(String name, Object value); 1204 1205 /** 1206 * Set an ordered bind parameter according to its position. Note that the 1207 * position starts at 1 to be consistent with JDBC PreparedStatement. You need 1208 * to set a parameter value for each ? you have in the query. 1209 * <pre>{@code 1210 * 1211 * // a query with a positioned parameter 1212 * String oql = "where status = ? order by id desc"; 1213 * 1214 * List<Order> list = DB.createQuery(Order.class, oql) 1215 * .setParameter(1, OrderStatus.NEW) 1216 * .findList(); 1217 * 1218 * }</pre> 1219 * 1220 * @param position the parameter bind position starting from 1 (not 0) 1221 * @param value the parameter bind value. 1222 */ 1223 Query<T> setParameter(int position, Object value); 1224 1225 /** 1226 * Bind the next positioned parameter. 1227 * 1228 * <pre>{@code 1229 * 1230 * // a query with a positioned parameters 1231 * String oql = "where status = ? and name = ?"; 1232 * 1233 * List<Order> list = DB.createQuery(Order.class, oql) 1234 * .setParameter(OrderStatus.NEW) 1235 * .setParameter("Rob") 1236 * .findList(); 1237 * 1238 * }</pre> 1239 */ 1240 Query<T> setParameter(Object value); 1241 1242 /** 1243 * Bind all the positioned parameters. 1244 * <p> 1245 * A convenience for multiple calls to {@link #setParameter(Object)} 1246 */ 1247 Query<T> setParameters(Object... values); 1248 1249 /** 1250 * Set the Id value to query. This is used with findOne(). 1251 * <p> 1252 * You can use this to have further control over the query. For example adding 1253 * fetch joins. 1254 * </p> 1255 * <pre>{@code 1256 * 1257 * Order order = DB.find(Order.class) 1258 * .setId(1) 1259 * .fetch("details") 1260 * .findOne(); 1261 * 1262 * // the order details were eagerly fetched 1263 * List<OrderDetail> details = order.getDetails(); 1264 * 1265 * }</pre> 1266 */ 1267 Query<T> setId(Object id); 1268 1269 /** 1270 * Return the Id value. 1271 */ 1272 Object getId(); 1273 1274 /** 1275 * Add a single Expression to the where clause returning the query. 1276 * <pre>{@code 1277 * 1278 * List<Order> newOrders = DB.find(Order.class) 1279 * .where().eq("status", Order.NEW) 1280 * .findList(); 1281 * ... 1282 * 1283 * }</pre> 1284 */ 1285 Query<T> where(Expression expression); 1286 1287 /** 1288 * Add Expressions to the where clause with the ability to chain on the 1289 * ExpressionList. You can use this for adding multiple expressions to the 1290 * where clause. 1291 * <pre>{@code 1292 * 1293 * List<Order> orders = DB.find(Order.class) 1294 * .where() 1295 * .eq("status", Order.NEW) 1296 * .ilike("customer.name","rob%") 1297 * .findList(); 1298 * 1299 * }</pre> 1300 * 1301 * @return The ExpressionList for adding expressions to. 1302 * @see Expr 1303 */ 1304 ExpressionList<T> where(); 1305 1306 /** 1307 * Add Full text search expressions for Document store queries. 1308 * <p> 1309 * This is currently ElasticSearch only and provides the full text 1310 * expressions such as Match and Multi-Match. 1311 * </p> 1312 * <p> 1313 * This automatically makes this query a "Doc Store" query and will execute 1314 * against the document store (ElasticSearch). 1315 * </p> 1316 * <p> 1317 * Expressions added here are added to the "query" section of an ElasticSearch 1318 * query rather than the "filter" section. 1319 * </p> 1320 * <p> 1321 * Expressions added to the where() are added to the "filter" section of an 1322 * ElasticSearch query. 1323 * </p> 1324 */ 1325 ExpressionList<T> text(); 1326 1327 /** 1328 * This applies a filter on the 'many' property list rather than the root 1329 * level objects. 1330 * <p> 1331 * Typically you will use this in a scenario where the cardinality is high on 1332 * the 'many' property you wish to join to. Say you want to fetch customers 1333 * and their associated orders... but instead of getting all the orders for 1334 * each customer you only want to get the new orders they placed since last 1335 * week. In this case you can use filterMany() to filter the orders. 1336 * </p> 1337 * <pre>{@code 1338 * 1339 * List<Customer> list = DB.find(Customer.class) 1340 * .fetch("orders") 1341 * .where().ilike("name", "rob%") 1342 * .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek) 1343 * .findList(); 1344 * 1345 * }</pre> 1346 * <p> 1347 * Please note you have to be careful that you add expressions to the correct 1348 * expression list - as there is one for the 'root level' and one for each 1349 * filterMany that you have. 1350 * </p> 1351 * 1352 * @param propertyName the name of the many property that you want to have a filter on. 1353 * @return the expression list that you add filter expressions for the many to. 1354 */ 1355 ExpressionList<T> filterMany(String propertyName); 1356 1357 /** 1358 * Add Expressions to the Having clause return the ExpressionList. 1359 * <p> 1360 * Currently only beans based on raw sql will use the having clause. 1361 * </p> 1362 * <p> 1363 * Note that this returns the ExpressionList (so you can add multiple 1364 * expressions to the query in a fluent API way). 1365 * </p> 1366 * 1367 * @return The ExpressionList for adding more expressions to. 1368 * @see Expr 1369 */ 1370 ExpressionList<T> having(); 1371 1372 /** 1373 * Add an expression to the having clause returning the query. 1374 * <p> 1375 * Currently only beans based on raw sql will use the having clause. 1376 * </p> 1377 * <p> 1378 * This is similar to {@link #having()} except it returns the query rather 1379 * than the ExpressionList. This is useful when you want to further specify 1380 * something on the query. 1381 * </p> 1382 * 1383 * @param addExpressionToHaving the expression to add to the having clause. 1384 * @return the Query object 1385 */ 1386 Query<T> having(Expression addExpressionToHaving); 1387 1388 /** 1389 * Set the order by clause replacing the existing order by clause if there is 1390 * one. 1391 * <p> 1392 * This follows SQL syntax using commas between each property with the 1393 * optional asc and desc keywords representing ascending and descending order 1394 * respectively. 1395 */ 1396 Query<T> orderBy(String orderByClause); 1397 1398 /** 1399 * Set the order by clause replacing the existing order by clause if there is 1400 * one. 1401 * <p> 1402 * This follows SQL syntax using commas between each property with the 1403 * optional asc and desc keywords representing ascending and descending order 1404 * respectively. 1405 */ 1406 Query<T> order(String orderByClause); 1407 1408 /** 1409 * Return the OrderBy so that you can append an ascending or descending 1410 * property to the order by clause. 1411 * <p> 1412 * This will never return a null. If no order by clause exists then an 'empty' 1413 * OrderBy object is returned. 1414 * <p> 1415 * This is the same as <code>orderBy()</code> 1416 */ 1417 OrderBy<T> order(); 1418 1419 /** 1420 * Return the OrderBy so that you can append an ascending or descending 1421 * property to the order by clause. 1422 * <p> 1423 * This will never return a null. If no order by clause exists then an 'empty' 1424 * OrderBy object is returned. 1425 * <p> 1426 * This is the same as <code>order()</code> 1427 */ 1428 OrderBy<T> orderBy(); 1429 1430 /** 1431 * Set an OrderBy object to replace any existing OrderBy clause. 1432 */ 1433 Query<T> setOrder(OrderBy<T> orderBy); 1434 1435 /** 1436 * Set an OrderBy object to replace any existing OrderBy clause. 1437 */ 1438 Query<T> setOrderBy(OrderBy<T> orderBy); 1439 1440 /** 1441 * Set whether this query uses DISTINCT. 1442 * <p> 1443 * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that 1444 * generally ORM queries include the "id" property and this doesn't make sense for distinct queries. 1445 * </p> 1446 * <pre>{@code 1447 * 1448 * List<Customer> customers = 1449 * DB.find(Customer.class) 1450 * .setDistinct(true) 1451 * .select("name") 1452 * .findList(); 1453 * 1454 * }</pre> 1455 */ 1456 Query<T> setDistinct(boolean isDistinct); 1457 1458 /** 1459 * Extended version for setDistinct in conjunction with "findSingleAttributeList"; 1460 * 1461 * <pre>{@code 1462 * 1463 * List<CountedValue<Order.Status>> orderStatusCount = 1464 * 1465 * DB.find(Order.class) 1466 * .select("status") 1467 * .where() 1468 * .gt("orderDate", LocalDate.now().minusMonths(3)) 1469 * 1470 * // fetch as single attribute with a COUNT 1471 * .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC) 1472 * .findSingleAttributeList(); 1473 * 1474 * for (CountedValue<Order.Status> entry : orderStatusCount) { 1475 * System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() ); 1476 * } 1477 * 1478 * // produces 1479 * 1480 * count:3 orderStatus:NEW 1481 * count:1 orderStatus:SHIPPED 1482 * count:1 orderStatus:COMPLETE 1483 * 1484 * }</pre> 1485 */ 1486 Query<T> setCountDistinct(CountDistinctOrder orderBy); 1487 1488 /** 1489 * Return the first row value. 1490 */ 1491 int getFirstRow(); 1492 1493 /** 1494 * Set the first row to return for this query. 1495 * 1496 * @param firstRow the first row to include in the query result. 1497 */ 1498 Query<T> setFirstRow(int firstRow); 1499 1500 /** 1501 * Return the max rows for this query. 1502 */ 1503 int getMaxRows(); 1504 1505 /** 1506 * Set the maximum number of rows to return in the query. 1507 * 1508 * @param maxRows the maximum number of rows to return in the query. 1509 */ 1510 Query<T> setMaxRows(int maxRows); 1511 1512 /** 1513 * Set the property to use as keys for a map. 1514 * <p> 1515 * If no property is set then the id property is used. 1516 * </p> 1517 * <pre>{@code 1518 * 1519 * // Assuming sku is unique for products... 1520 * 1521 * Map<String,Product> productMap = DB.find(Product.class) 1522 * .setMapKey("sku") // sku map keys... 1523 * .findMap(); 1524 * 1525 * }</pre> 1526 * 1527 * @param mapKey the property to use as keys for a map. 1528 */ 1529 Query<T> setMapKey(String mapKey); 1530 1531 /** 1532 * Set this to false to not use the bean cache. 1533 * <p> 1534 * This method is now superseded by {@link #setBeanCacheMode(CacheMode)} 1535 * which provides more explicit options controlled bean cache use. 1536 * </p> 1537 * <p> 1538 * This method is likely to be deprecated in the future with migration 1539 * over to setUseBeanCache(). 1540 * </p> 1541 */ 1542 default Query<T> setUseCache(boolean useCache) { 1543 return setBeanCacheMode(useCache ? CacheMode.ON : CacheMode.OFF); 1544 } 1545 1546 /** 1547 * Set the mode to use the bean cache when executing this query. 1548 * <p> 1549 * By default "find by id" and "find by natural key" will use the bean cache 1550 * when bean caching is enabled. Setting this to false means that the query 1551 * will not use the bean cache and instead hit the database. 1552 * </p> 1553 * <p> 1554 * By default findList() with natural keys will not use the bean cache. In that 1555 * case we need to explicitly use the bean cache. 1556 * </p> 1557 */ 1558 Query<T> setBeanCacheMode(CacheMode beanCacheMode); 1559 1560 /** 1561 * Set the {@link CacheMode} to use the query for executing this query. 1562 */ 1563 Query<T> setUseQueryCache(CacheMode queryCacheMode); 1564 1565 /** 1566 * Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>. 1567 */ 1568 default Query<T> setUseQueryCache(boolean enabled) { 1569 return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF); 1570 } 1571 1572 /** 1573 * Set the profile location of this query. This is used to relate query execution metrics 1574 * back to a location like a specific line of code. 1575 */ 1576 Query<T> setProfileLocation(ProfileLocation profileLocation); 1577 1578 /** 1579 * Set a label on the query. 1580 * <p> 1581 * This label can be used to help identify query performance metrics but we can also use 1582 * profile location enhancement on Finders so for some that would be a better option. 1583 * </p> 1584 */ 1585 Query<T> setLabel(String label); 1586 1587 /** 1588 * Set to true if this query should execute against the doc store. 1589 * <p> 1590 * When setting this you may also consider disabling lazy loading. 1591 * </p> 1592 */ 1593 Query<T> setUseDocStore(boolean useDocStore); 1594 1595 /** 1596 * When set to true when you want the returned beans to be read only. 1597 */ 1598 Query<T> setReadOnly(boolean readOnly); 1599 1600 /** 1601 * Will be deprecated - migrate to use setBeanCacheMode(CacheMode.RECACHE). 1602 * <p> 1603 * When set to true all the beans from this query are loaded into the bean cache. 1604 */ 1605 Query<T> setLoadBeanCache(boolean loadBeanCache); 1606 1607 /** 1608 * Set a timeout on this query. 1609 * <p> 1610 * This will typically result in a call to setQueryTimeout() on a 1611 * preparedStatement. If the timeout occurs an exception will be thrown - this 1612 * will be a SQLException wrapped up in a PersistenceException. 1613 * </p> 1614 * 1615 * @param secs the query timeout limit in seconds. Zero means there is no limit. 1616 */ 1617 Query<T> setTimeout(int secs); 1618 1619 /** 1620 * A hint which for JDBC translates to the Statement.fetchSize(). 1621 * <p> 1622 * Gives the JDBC driver a hint as to the number of rows that should be 1623 * fetched from the database when more rows are needed for ResultSet. 1624 * </p> 1625 * <p> 1626 * Note that internally findEach and findEachWhile will set the fetch size 1627 * if it has not already as these queries expect to process a lot of rows. 1628 * If we didn't then Postgres and MySql for example would eagerly pull back 1629 * all the row data and potentially consume a lot of memory in the process. 1630 * </p> 1631 * <p> 1632 * As findEach and findEachWhile automatically set the fetch size we don't have 1633 * to do so generally but we might still wish to for tuning a specific use case. 1634 * </p> 1635 */ 1636 Query<T> setBufferFetchSizeHint(int fetchSize); 1637 1638 /** 1639 * Return the sql that was generated for executing this query. 1640 * <p> 1641 * This is only available after the query has been executed and provided only 1642 * for informational purposes. 1643 * </p> 1644 */ 1645 String getGeneratedSql(); 1646 1647 /** 1648 * Execute the query with the given lock type and WAIT. 1649 * <p> 1650 * Note that <code>forUpdate()</code> is the same as 1651 * <code>withLock(LockType.UPDATE)</code>. 1652 * <p> 1653 * Provides us with the ability to explicitly use Postgres 1654 * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks. 1655 */ 1656 Query<T> withLock(LockType lockType); 1657 1658 /** 1659 * Execute the query with the given lock type and lock wait. 1660 * <p> 1661 * Note that <code>forUpdateNoWait()</code> is the same as 1662 * <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>. 1663 * <p> 1664 * Provides us with the ability to explicitly use Postgres 1665 * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks. 1666 */ 1667 Query<T> withLock(LockType lockType, LockWait lockWait); 1668 1669 /** 1670 * Execute using "for update" clause which results in the DB locking the record. 1671 * <p> 1672 * The same as <code>withLock(LockType.UPDATE, LockWait.WAIT)</code>. 1673 */ 1674 Query<T> forUpdate(); 1675 1676 /** 1677 * Execute using "for update" clause with "no wait" option. 1678 * <p> 1679 * This is typically a Postgres and Oracle only option at this stage. 1680 * <p> 1681 * The same as <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>. 1682 */ 1683 Query<T> forUpdateNoWait(); 1684 1685 /** 1686 * Execute using "for update" clause with "skip locked" option. 1687 * <p> 1688 * This is typically a Postgres and Oracle only option at this stage. 1689 * <p> 1690 * The same as <code>withLock(LockType.UPDATE, LockWait.SKIPLOCKED)</code>. 1691 */ 1692 Query<T> forUpdateSkipLocked(); 1693 1694 /** 1695 * Return true if this query has forUpdate set. 1696 */ 1697 boolean isForUpdate(); 1698 1699 /** 1700 * Return the "for update" wait mode to use. 1701 */ 1702 LockWait getForUpdateLockWait(); 1703 1704 /** 1705 * Return the lock type (strength) to use with "for update". 1706 */ 1707 LockType getForUpdateLockType(); 1708 1709 /** 1710 * Set root table alias. 1711 */ 1712 Query<T> alias(String alias); 1713 1714 /** 1715 * Set the base table to use for this query. 1716 * <p> 1717 * Typically this is used when a table has partitioning and we wish to specify a specific 1718 * partition/table to query against. 1719 * </p> 1720 * <pre>{@code 1721 * 1722 * QOrder() 1723 * .setBaseTable("order_2019_05") 1724 * .status.equalTo(Status.NEW) 1725 * .findList(); 1726 * 1727 * }</pre> 1728 */ 1729 Query<T> setBaseTable(String baseTable); 1730 1731 /** 1732 * Return the type of beans being queried. 1733 */ 1734 Class<T> getBeanType(); 1735 1736 /** 1737 * Restrict the query to only return subtypes of the given inherit type. 1738 * 1739 * <pre>{@code 1740 * 1741 * List<Animal> animals = 1742 * new QAnimal() 1743 * .name.startsWith("Fluffy") 1744 * .setInheritType(Cat.class) 1745 * .findList(); 1746 * 1747 * }</pre> 1748 * 1749 * @param type An inheritance subtype of the 1750 */ 1751 Query<T> setInheritType(Class<? extends T> type); 1752 1753 /** 1754 * Returns the inherit type. This is normally the same as getBeanType() returns as long as no other type is set. 1755 */ 1756 Class<? extends T> getInheritType(); 1757 1758 /** 1759 * Return the type of query being executed. 1760 */ 1761 QueryType getQueryType(); 1762 1763 /** 1764 * Set true if you want to disable lazy loading. 1765 * <p> 1766 * That is, once the object graph is returned further lazy loading is disabled. 1767 * </p> 1768 */ 1769 Query<T> setDisableLazyLoading(boolean disableLazyLoading); 1770 1771 /** 1772 * Returns the set of properties or paths that are unknown (do not map to known properties or paths). 1773 * <p> 1774 * Validate the query checking the where and orderBy expression paths to confirm if 1775 * they represent valid properties or paths for the given bean type. 1776 * </p> 1777 */ 1778 Set<String> validate(); 1779 1780 /** 1781 * Controls, if paginated queries should always append an 'order by id' statement at the end to 1782 * guarantee a deterministic sort result. This may affect performance. 1783 * If this is not enabled, and an orderBy is set on the query, it's up to the programmer that 1784 * this query provides a deterministic result. 1785 */ 1786 Query<T> orderById(boolean orderById); 1787 1788}