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