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