001package com.avaje.ebean; 002 003import com.avaje.ebean.bean.EntityBean; 004import com.avaje.ebean.text.PathProperties; 005import com.avaje.ebean.util.ClassUtil; 006import org.jetbrains.annotations.Nullable; 007 008import javax.persistence.MappedSuperclass; 009import java.util.List; 010import java.util.Map; 011import java.util.Set; 012import java.util.UUID; 013 014/** 015 * A MappedSuperclass base class that provides convenience methods for inserting, updating and 016 * deleting beans. 017 * 018 * <p> 019 * By having your entity beans extend this it provides a 'Active Record' style programming model for 020 * Ebean users. 021 * 022 * <p> 023 * Note that there is a avaje-ebeanorm-mocker project that enables you to use Mockito or similar 024 * tools to still mock out the underlying 'default EbeanServer' for testing purposes. 025 * 026 * <p> 027 * You may choose not use this Model mapped superclass if you don't like the 'Active Record' style 028 * or if you believe it 'pollutes' your entity beans. 029 * 030 * <p> 031 * You can use Dependency Injection like Guice or Spring to construct and wire a EbeanServer instance 032 * and have that same instance used with this Model and Finder. The way that works is that when the 033 * DI container creates the EbeanServer instance it can be registered with the Ebean singleton. In this 034 * way the EbeanServer instance can be injected as per normal Guice / Spring dependency injection and 035 * that same instance also used to support the Model and Finder active record style. 036 * 037 * <p> 038 * If you choose to use the Model mapped superclass you will probably also chose to additionally add 039 * a {@link Find} as a public static field to complete the active record pattern and provide a 040 * relatively nice clean way to write queries. 041 * 042 * <h3>Typical common @MappedSuperclass</h3> 043 * <pre>{@code 044 * 045 * // Typically there is a common base model that has some 046 * // common properties like the ones below 047 * 048 * @MappedSuperclass 049 * public class BaseModel extends Model { 050 * 051 * @Id Long id; 052 * 053 * @Version Long version; 054 * 055 * @CreatedTimestamp Timestamp whenCreated; 056 * 057 * @UpdatedTimestamp Timestamp whenUpdated; 058 * 059 * ... 060 * 061 * }</pre> 062 * 063 * <h3>Extend the Model</h3> 064 * <pre>{@code 065 * 066 * // Extend the mappedSuperclass 067 * 068 * @Entity @Table(name="oto_account") 069 * public class Customer extends BaseModel { 070 * 071 * // Add a static Find 072 * // ... with Long being the type of our @Id property. 073 * // ... Note the {} at the end as Find is an abstract class. 074 * 075 * public static final Find<Long,Account> find = new Find<Long,Account>(){}; 076 * 077 * String name; 078 * ... 079 * } 080 * 081 * }</pre> 082 * 083 * <h3>Modal: save()</h3> 084 * <pre>{@code 085 * 086 * // Active record style ... save(), delete() etc 087 * Customer customer = new Customer(); 088 * customer.setName("AC234"); 089 * 090 * // save() method inherited from Model 091 * customer.save(); 092 * 093 * }</pre> 094 * 095 * <h3>Find byId</h3> 096 * <pre>{@code 097 * 098 * // find byId 099 * Customer customer = Customer.find.byId(42); 100 * 101 * }</pre> 102 * 103 * <h3>Find where</h3> 104 * <pre>{@code 105 * 106 * // find where ... 107 * List<Customer> customers = 108 * Customer.find 109 * .where().gt("startDate", lastMonth) 110 * .findList(); 111 * 112 * }</pre> 113 */ 114@MappedSuperclass 115public abstract class Model { 116 117 /** 118 * Return the underlying 'default' EbeanServer. 119 * 120 * <p> 121 * This provides full access to the API such as explicit transaction demarcation etc. 122 * 123 * <p> 124 * Example: 125 * <pre>{@code 126 * 127 * Transaction transaction = Customer.db().beginTransaction(); 128 * try { 129 * 130 * // turn off cascade persist for this transaction 131 * transaction.setPersistCascade(false); 132 * 133 * // extra control over jdbc batching for this transaction 134 * transaction.setBatchGetGeneratedKeys(false); 135 * transaction.setBatchMode(true); 136 * transaction.setBatchSize(20); 137 * 138 * Customer customer = new Customer(); 139 * customer.setName("Roberto"); 140 * customer.save(); 141 * 142 * Customer otherCustomer = new Customer(); 143 * otherCustomer.setName("Franko"); 144 * otherCustomer.save(); 145 * 146 * transaction.commit(); 147 * 148 * } finally { 149 * transaction.end(); 150 * } 151 * 152 * }</pre> 153 */ 154 public static EbeanServer db() { 155 return Ebean.getDefaultServer(); 156 } 157 158 /** 159 * Return a named EbeanServer that is typically different to the default server. 160 * 161 * <p> 162 * If you are using multiple databases then each database has a name and maps to a single 163 * EbeanServer. You can use this method to get an EbeanServer for another database. 164 * 165 * @param server 166 * The name of the EbeanServer. If this is null then the default EbeanServer is returned. 167 */ 168 public static EbeanServer db(String server) { 169 return Ebean.getServer(server); 170 } 171 172 /** 173 * Marks the entity bean as dirty. 174 * <p> 175 * This is used so that when a bean that is otherwise unmodified is updated the version 176 * property is updated. 177 * <p> 178 * An unmodified bean that is saved or updated is normally skipped and this marks the bean as 179 * dirty so that it is not skipped. 180 * 181 * <pre>{@code 182 * 183 * Customer customer = Customer.find.byId(id); 184 * 185 * // mark the bean as dirty so that a save() or update() will 186 * // increment the version property 187 * customer.markAsDirty(); 188 * customer.save(); 189 * 190 * }</pre> 191 * 192 * @see EbeanServer#markAsDirty(Object) 193 */ 194 public void markAsDirty() { 195 db().markAsDirty(this); 196 } 197 198 /** 199 * Mark the property as unset or 'not loaded'. 200 * <p> 201 * This would be used to specify a property that we did not wish to include in a stateless update. 202 * </p> 203 * <pre>{@code 204 * 205 * // populate an entity bean from JSON or whatever 206 * User user = ...; 207 * 208 * // mark the email property as 'unset' so that it is not 209 * // included in a 'stateless update' 210 * user.markPropertyUnset("email"); 211 * 212 * user.update(); 213 * 214 * }</pre> 215 * 216 * @param propertyName the name of the property on the bean to be marked as 'unset' 217 */ 218 public void markPropertyUnset(String propertyName) { 219 ((EntityBean)this)._ebean_getIntercept().setPropertyLoaded(propertyName, false); 220 } 221 222 /** 223 * Insert or update this entity depending on its state. 224 * 225 * <p> 226 * Ebean will detect if this is a new bean or a previously fetched bean and perform either an 227 * insert or an update based on that. 228 * 229 * @see EbeanServer#save(Object) 230 */ 231 public void save() { 232 db().save(this); 233 } 234 235 /** 236 * Update this entity. 237 * 238 * @see EbeanServer#update(Object) 239 */ 240 public void update() { 241 db().update(this); 242 } 243 244 /** 245 * Insert this entity. 246 * 247 * @see EbeanServer#insert(Object) 248 */ 249 public void insert() { 250 db().insert(this); 251 } 252 253 /** 254 * Delete this entity. 255 * 256 * @see EbeanServer#delete(Object) 257 */ 258 public void delete() { 259 db().delete(this); 260 } 261 262 /** 263 * Perform an update using this entity against the specified server. 264 */ 265 public void update(String server) { 266 db(server).update(this); 267 } 268 269 /** 270 * Perform an insert using this entity against the specified server. 271 */ 272 public void insert(String server) { 273 db(server).insert(this); 274 } 275 276 /** 277 * Perform a delete using this entity against the specified server. 278 */ 279 public void delete(String server) { 280 db(server).delete(this); 281 } 282 283 /** 284 * Refreshes this entity from the database. 285 * 286 * @see EbeanServer#refresh(Object) 287 */ 288 public void refresh() { 289 db().refresh(this); 290 } 291 292 /** 293 * A concrete implementation of Find. 294 * <p> 295 * It should be preferred to use {@link Find} instead of Finder as that can use reflection to determine the class 296 * literal type of the entity bean. 297 * </p> 298 * @param <I> type of the Id property 299 * @param <T> type of the entity bean 300 */ 301 public static class Finder<I, T> extends Find<I, T> { 302 303 /** 304 * Create with the type of the entity bean. 305 * 306 * <pre>{@code 307 * 308 * @Entity 309 * public class Customer extends BaseModel { 310 * 311 * public static final Finder<Long,Customer> find = new Finder<Long,Customer>(Customer.class); 312 * ... 313 * 314 * }</pre> 315 * 316 * <p/> 317 * The preferred approach is to instead use <code>Find</code> as below. This approach is more DRY in that it does 318 * not require the class literal Customer.class to be passed into the constructor. 319 * 320 * <pre>{@code 321 * 322 * @Entity 323 * public class Customer extends BaseModel { 324 * 325 * public static final Find<Long,Customer> find = new Find<Long,Customer>(){}; 326 * ... 327 * 328 * }</pre> 329 */ 330 public Finder(Class<T> type) { 331 super(null, type); 332 } 333 334 /** 335 * Create with the type of the entity bean and specific server name. 336 */ 337 public Finder(String serverName, Class<T> type) { 338 super(serverName, type); 339 } 340 341 /** 342 * Please migrate to use {@link Find} or constructor <code>Finder(Class)</code> that 343 * does not have the idType parameter. 344 * <p/> 345 * Create with the type of the ID property and entity bean and specific server name. 346 * 347 * @deprecated 348 */ 349 public Finder(Class<I> idType, Class<T> type) { 350 super(null, type); 351 } 352 353 /** 354 * Please migrate to use the constructor <code>Finder(String, Class)</code> that 355 * does not have the idType parameter. 356 * <p/> 357 * Create with the type of the ID property and entity bean and specific server name. 358 * 359 * @deprecated 360 */ 361 public Finder(String serverName, Class<I> idType, Class<T> type) { 362 super(serverName, type); 363 } 364 } 365 366 /** 367 * Helper object for performing queries. 368 * 369 * <p> 370 * Typically a Find instance is defined as a public static field on an entity bean class to provide a 371 * nice way to write queries. 372 * 373 * <h3>Example use:</h3> 374 * 375 * <pre>{@code 376 * 377 * @Entity 378 * public class Customer extends BaseModel { 379 * 380 * public static final Find<Long,Customer> find = new Find<Long,Customer>(){}; 381 * 382 * ... 383 * 384 * }</pre> 385 * <p/> 386 * This enables you to write code like: 387 * <pre>{@code 388 * 389 * Customer customer = Customer.find.byId(42L); 390 * 391 * List<Customer> customers = 392 * Customer.find 393 * .select("name, dateOfBirth") 394 * .findList(); 395 * 396 * }</pre> 397 * 398 * <h3>Kotlin</h3> 399 * In Kotlin you would typically create Find as a companion object. 400 * <pre>{@code 401 * 402 * // kotlin 403 * companion object : Model.Find<Long, Product>() {} 404 * 405 * }</pre> 406 * @param <I> 407 * The Id type. This is most often a {@link Long} but is also often a {@link UUID} or 408 * {@link String}. 409 * 410 * @param <T> 411 * The entity bean type 412 */ 413 public static abstract class Find<I, T> { 414 415 /** 416 * The entity bean type. 417 */ 418 private final Class<T> type; 419 420 /** 421 * The name of the EbeanServer, null for the default server. 422 */ 423 private final String serverName; 424 425 /** 426 * Creates a finder for entity of type <code>T</code> with ID of type <code>I</code>. 427 * <p/> 428 * Typically you create Find as a public static field on each entity bean as the example below. 429 * 430 * <p/> 431 * Note that Find is an abstract class and hence <code>{}</code> is required. This is done so 432 * that the type (class literal) of the entity bean can be derived from the generics parameter. 433 * 434 * <pre>{@code 435 * 436 * @Entity 437 * public class Customer extends BaseModel { 438 * 439 * // Note the trailing {} as Find is an abstract class. 440 * // We do this so that we can derive the type literal Customer.class 441 * // via reflection 442 * public static final Find<Long,Customer> find = new Find<Long,Customer>(){}; 443 * ... 444 * 445 * }</pre> 446 * <p/> 447 * This enables you to write code like: 448 * <pre>{@code 449 * 450 * Customer customer = Customer.find.byId(42L); 451 * 452 * List<Customer> customers = 453 * Customer.find 454 * .select("name, email, dateOfBirth") 455 * .findList(); 456 * 457 * }</pre> 458 * 459 * <h3>Kotlin</h3> 460 * In Kotlin you would typically create it as a companion object. 461 * 462 * <pre>{@code 463 * 464 * // kotlin 465 * companion object : Model.Find<Long, Product>() {} 466 * 467 * }</pre> 468 */ 469 @SuppressWarnings("unchecked") 470 public Find() { 471 this.serverName = null; 472 this.type = (Class<T>)ClassUtil.getSecondArgumentType(getClass()); 473 } 474 475 /** 476 * Construct passing the class literal type of the entity type. 477 */ 478 protected Find(String serverName, Class<T> type) { 479 this.serverName = serverName; 480 this.type = type; 481 } 482 483 /** 484 * Return the underlying 'default' EbeanServer. 485 * 486 * <p> 487 * This provides full access to the API such as explicit transaction demarcation etc. 488 * 489 */ 490 public EbeanServer db() { 491 return Ebean.getServer(serverName); 492 } 493 494 /** 495 * Return typically a different EbeanServer to the default. 496 * <p> 497 * This is equivilent to {@link Ebean#getServer(String)} 498 * 499 * @param server 500 * The name of the EbeanServer. If this is null then the default EbeanServer is 501 * returned. 502 */ 503 public EbeanServer db(String server) { 504 return Ebean.getServer(server); 505 } 506 507 /** 508 * Creates a Finder for the named EbeanServer. 509 * 510 * <p> 511 * Create and return a new Finder for a different server. 512 */ 513 public Finder<I, T> on(String server) { 514 return new Finder<I, T>(server, type); 515 } 516 517 /** 518 * Delete a bean by Id. 519 * <p> 520 * Equivalent to {@link EbeanServer#delete(Class, Object)} 521 */ 522 public void deleteById(I id) { 523 db().delete(type, id); 524 } 525 526 /** 527 * Retrieves all entities of the given type. 528 * 529 * <p> 530 * This is the same as (synonym for) {@link #findList()} 531 */ 532 public List<T> all() { 533 return findList(); 534 } 535 536 /** 537 * Retrieves an entity by ID. 538 * 539 * <p> 540 * Equivalent to {@link EbeanServer#find(Class, Object)} 541 */ 542 @Nullable 543 public T byId(I id) { 544 return db().find(type, id); 545 } 546 547 /** 548 * Creates an entity reference for this ID. 549 * 550 * <p> 551 * Equivalent to {@link EbeanServer#getReference(Class, Object)} 552 */ 553 public T ref(I id) { 554 return db().getReference(type, id); 555 } 556 557 /** 558 * Creates a filter for sorting and filtering lists of entities locally without going back to 559 * the database. 560 * <p> 561 * Equivalent to {@link EbeanServer#filter(Class)} 562 */ 563 public Filter<T> filter() { 564 return db().filter(type); 565 } 566 567 /** 568 * Creates a query. 569 * <p> 570 * Equivalent to {@link EbeanServer#find(Class)} 571 */ 572 public Query<T> query() { 573 return db().find(type); 574 } 575 576 /** 577 * Creates a query applying the path properties to set the select and fetch clauses. 578 * <p> 579 * Equivalent to {@link Query#apply(com.avaje.ebean.text.PathProperties)} 580 */ 581 public Query<T> apply(PathProperties pathProperties) { 582 return db().find(type).apply(pathProperties); 583 } 584 585 /** 586 * Returns the next identity value. 587 * 588 * @see EbeanServer#nextId(Class) 589 */ 590 @SuppressWarnings("unchecked") 591 public I nextId() { 592 return (I) db().nextId(type); 593 } 594 595 /** 596 * Executes a query and returns the results as a list of IDs. 597 * <p> 598 * Equivalent to {@link Query#findIds()} 599 */ 600 public List<Object> findIds() { 601 return query().findIds(); 602 } 603 604 /** 605 * Execute the query consuming each bean one at a time. 606 * <p> 607 * This is generally used to process large queries where unlike findList 608 * you do not want to hold all the results in memory at once but instead 609 * process them one at a time (requiring far less memory). 610 * </p> 611 * Equivalent to {@link Query#findEach(QueryEachConsumer)} 612 */ 613 public void findEach(QueryEachConsumer<T> consumer) { 614 query().findEach(consumer); 615 } 616 617 /** 618 * Execute the query consuming each bean one at a time. 619 * <p> 620 * Equivalent to {@link Query#findEachWhile(QueryEachWhileConsumer)} 621 * <p> 622 * This is similar to #findEach except that you return boolean 623 * true to continue processing beans and return false to stop 624 * processing early. 625 * </p> 626 * <p> 627 * This is generally used to process large queries where unlike findList 628 * you do not want to hold all the results in memory at once but instead 629 * process them one at a time (requiring far less memory). 630 * </p> 631 * Equivalent to {@link Query#findEachWhile(QueryEachWhileConsumer)} 632 */ 633 public void findEachWhile(QueryEachWhileConsumer<T> consumer) { 634 query().findEachWhile(consumer); 635 } 636 637 /** 638 * Retrieves all entities of the given type. 639 * <p> 640 * The same as {@link #all()} 641 * <p> 642 * Equivalent to {@link Query#findList()} 643 */ 644 public List<T> findList() { 645 return query().findList(); 646 } 647 648 /** 649 * Returns all the entities of the given type as a set. 650 * <p> 651 * Equivalent to {@link Query#findSet()} 652 */ 653 public Set<T> findSet() { 654 return query().findSet(); 655 } 656 657 /** 658 * Retrieves all entities of the given type as a map of objects. 659 * <p> 660 * Equivalent to {@link Query#findMap()} 661 */ 662 public Map<?, T> findMap() { 663 return query().findMap(); 664 } 665 666 /** 667 * Executes the query and returns the results as a map of the objects specifying the map key 668 * property. 669 * <p> 670 * Equivalent to {@link Query#findMap(String, Class)} 671 */ 672 public <K> Map<K, T> findMap(String keyProperty, Class<K> keyType) { 673 return query().findMap(keyProperty, keyType); 674 } 675 676 /** 677 * Return a PagedList of all entities of the given type (use where() to specify predicates as 678 * needed). 679 * <p> 680 * Equivalent to {@link Query#findPagedList(int, int)} 681 */ 682 public PagedList<T> findPagedList(int pageIndex, int pageSize) { 683 return query().findPagedList(pageIndex, pageSize); 684 } 685 686 /** 687 * Executes a find row count query in a background thread. 688 * <p> 689 * Equivalent to {@link Query#findFutureRowCount()} 690 */ 691 public FutureRowCount<T> findFutureRowCount() { 692 return query().findFutureRowCount(); 693 } 694 695 /** 696 * Returns the total number of entities for this type. * 697 * <p> 698 * Equivalent to {@link Query#findRowCount()} 699 */ 700 public int findRowCount() { 701 return query().findRowCount(); 702 } 703 704 /** 705 * Returns the <code>ExpressionFactory</code> used by this query. 706 */ 707 public ExpressionFactory getExpressionFactory() { 708 return query().getExpressionFactory(); 709 } 710 711 /** 712 * Explicitly sets a comma delimited list of the properties to fetch on the 'main' entity bean, 713 * to load a partial object. 714 * <p> 715 * Equivalent to {@link Query#select(String)} 716 */ 717 public Query<T> select(String fetchProperties) { 718 return query().select(fetchProperties); 719 } 720 721 /** 722 * Specifies a path to load including all its properties. 723 * <p> 724 * Equivalent to {@link Query#fetch(String)} 725 */ 726 public Query<T> fetch(String path) { 727 return query().fetch(path); 728 } 729 730 /** 731 * Additionally specifies a <code>FetchConfig</code> to specify a 'query join' and/or define the 732 * lazy loading query. 733 * <p> 734 * Equivalent to {@link Query#fetch(String, FetchConfig)} 735 */ 736 public Query<T> fetch(String path, FetchConfig joinConfig) { 737 return query().fetch(path, joinConfig); 738 } 739 740 /** 741 * Specifies a path to fetch with a specific list properties to include, to load a partial 742 * object. 743 * <p> 744 * Equivalent to {@link Query#fetch(String, String)} 745 */ 746 public Query<T> fetch(String path, String fetchProperties) { 747 return query().fetch(path, fetchProperties); 748 } 749 750 /** 751 * Additionally specifies a <code>FetchConfig</code> to use a separate query or lazy loading to 752 * load this path. 753 * <p> 754 * Equivalent to {@link Query#fetch(String, String, FetchConfig)} 755 */ 756 public Query<T> fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig) { 757 return query().fetch(assocProperty, fetchProperties, fetchConfig); 758 } 759 760 /** 761 * Adds expressions to the <code>where</code> clause with the ability to chain on the 762 * <code>ExpressionList</code>. 763 * <p> 764 * Equivalent to {@link Query#where()} 765 */ 766 public ExpressionList<T> where() { 767 return query().where(); 768 } 769 770 /** 771 * Returns the <code>order by</code> clause so that you can append an ascending or descending 772 * property to the <code>order by</code> clause. 773 * <p> 774 * This is exactly the same as {@link #orderBy}. 775 * <p> 776 * Equivalent to {@link Query#order()} 777 */ 778 public OrderBy<T> order() { 779 return query().order(); 780 } 781 782 /** 783 * Sets the <code>order by</code> clause, replacing the existing <code>order by</code> clause if 784 * there is one. 785 * <p> 786 * This is exactly the same as {@link #orderBy(String)}. 787 */ 788 public Query<T> order(String orderByClause) { 789 return query().order(orderByClause); 790 } 791 792 /** 793 * Returns the <code>order by</code> clause so that you can append an ascending or descending 794 * property to the <code>order by</code> clause. 795 * <p> 796 * This is exactly the same as {@link #order}. 797 * <p> 798 * Equivalent to {@link Query#orderBy()} 799 */ 800 public OrderBy<T> orderBy() { 801 return query().orderBy(); 802 } 803 804 /** 805 * Set the <code>order by</code> clause replacing the existing <code>order by</code> clause if 806 * there is one. 807 * <p> 808 * This is exactly the same as {@link #order(String)}. 809 */ 810 public Query<T> orderBy(String orderByClause) { 811 return query().orderBy(orderByClause); 812 } 813 814 /** 815 * Sets the first row to return for this query. 816 * <p> 817 * Equivalent to {@link Query#setFirstRow(int)} 818 */ 819 public Query<T> setFirstRow(int firstRow) { 820 return query().setFirstRow(firstRow); 821 } 822 823 /** 824 * Sets the maximum number of rows to return in the query. 825 * <p> 826 * Equivalent to {@link Query#setMaxRows(int)} 827 */ 828 public Query<T> setMaxRows(int maxRows) { 829 return query().setMaxRows(maxRows); 830 } 831 832 /** 833 * Sets the ID value to query. 834 * 835 * <p> 836 * Use this to perform a find byId query but with additional control over the query such as 837 * using select and fetch to control what parts of the object graph are returned. 838 * <p> 839 * Equivalent to {@link Query#setId(Object)} 840 */ 841 public Query<T> setId(Object id) { 842 return query().setId(id); 843 } 844 845 /** 846 * Create and return a new query using the OQL. 847 * <p> 848 * Equivalent to {@link EbeanServer#createQuery(Class, String)} 849 */ 850 public Query<T> setQuery(String oql) { 851 return db().createQuery(type, oql); 852 } 853 854 /** 855 * Create and return a new query based on the <code>RawSql</code>. 856 * <p> 857 * Equivalent to {@link Query#setRawSql(RawSql)} 858 */ 859 public Query<T> setRawSql(RawSql rawSql) { 860 return query().setRawSql(rawSql); 861 } 862 863 /** 864 * Create a query with explicit 'AutoTune' use. 865 */ 866 public Query<T> setAutoTune(boolean autoTune) { 867 return query().setAutoTune(autoTune); 868 } 869 870 /** 871 * Create a query with the select with "for update" specified. 872 * 873 * <p> 874 * This will typically create row level database locks on the selected rows. 875 */ 876 public Query<T> setForUpdate(boolean forUpdate) { 877 return query().setForUpdate(forUpdate); 878 } 879 880 /** 881 * Create a query specifying whether the returned beans will be read-only. 882 */ 883 public Query<T> setReadOnly(boolean readOnly) { 884 return query().setReadOnly(readOnly); 885 } 886 887 /** 888 * Create a query specifying if the beans should be loaded into the L2 cache. 889 */ 890 public Query<T> setLoadBeanCache(boolean loadBeanCache) { 891 return query().setLoadBeanCache(loadBeanCache); 892 } 893 894 /** 895 * Create a query specifying if the L2 bean cache should be used. 896 */ 897 public Query<T> setUseCache(boolean useBeanCache) { 898 return query().setUseCache(useBeanCache); 899 } 900 901 /** 902 * Create a query specifying if the L2 query cache should be used. 903 */ 904 public Query<T> setUseQueryCache(boolean useQueryCache) { 905 return query().setUseQueryCache(useQueryCache); 906 } 907 908 } 909}