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