001package com.avaje.ebean; 002 003import com.avaje.ebean.annotation.CacheStrategy; 004import com.avaje.ebean.cache.ServerCacheManager; 005import com.avaje.ebean.config.ServerConfig; 006import com.avaje.ebean.meta.MetaInfoManager; 007import com.avaje.ebean.plugin.SpiServer; 008import com.avaje.ebean.text.csv.CsvReader; 009import com.avaje.ebean.text.json.JsonContext; 010import org.jetbrains.annotations.Nullable; 011 012import javax.persistence.NonUniqueResultException; 013import javax.persistence.OptimisticLockException; 014import javax.persistence.PersistenceException; 015import java.util.Collection; 016import java.util.List; 017import java.util.Map; 018import java.util.Set; 019 020/** 021 * Provides the API for fetching and saving beans to a particular DataSource. 022 * <p> 023 * <b>Registration with the Ebean Singleton:</b><br/> 024 * When a EbeanServer is constructed it can be registered with the Ebean 025 * singleton (see {@link ServerConfig#setRegister(boolean)}). The Ebean 026 * singleton is essentially a map of EbeanServer's that have been registered 027 * with it. The EbeanServer can then be retrieved later via 028 * {@link Ebean#getServer(String)}. 029 * </p> 030 * <p> 031 * <b>The 'default' EbeanServer</b><br/> 032 * One EbeanServer can be designated as the 'default' or 'primary' EbeanServer 033 * (see {@link ServerConfig#setDefaultServer(boolean)}. Many methods on Ebean 034 * such as {@link Ebean#find(Class)} etc are actually just a convenient way to 035 * call methods on the 'default/primary' EbeanServer. This is handy for 036 * applications that use a single DataSource. 037 * <p> 038 * There is one EbeanServer per Database (javax.sql.DataSource). One EbeanServer 039 * is referred to as the <em>'default'</em> server and that is the one that 040 * Ebean methods such as {@link Ebean#find(Class)} use. 041 * </p> 042 * <p> 043 * <b>Constructing a EbeanServer</b><br/> 044 * EbeanServer's are constructed by the EbeanServerFactory. They can be created 045 * programmatically via {@link EbeanServerFactory#create(ServerConfig)} or they 046 * can be automatically constructed on demand using configuration information in 047 * the ebean.properties file. 048 * </p> 049 * <p> 050 * Example: Get a EbeanServer 051 * </p> 052 * 053 * <pre>{@code 054 * // Get access to the Human Resources EbeanServer/Database 055 * EbeanServer hrServer = Ebean.getServer("HR"); 056 * 057 * 058 * // fetch contact 3 from the HR database Contact contact = 059 * hrServer.find(Contact.class, new Integer(3)); 060 * 061 * contact.setStatus("INACTIVE"); ... 062 * 063 * // save the contact back to the HR database hrServer.save(contact); 064 * }</pre> 065 * 066 * <p> 067 * <b>EbeanServer has more API than Ebean</b><br/> 068 * EbeanServer provides additional API compared with Ebean. For example it 069 * provides more control over the use of Transactions that is not available in 070 * the Ebean API. 071 * </p> 072 * <p> 073 * <em>External Transactions:</em> If you wanted to use transactions created 074 * externally to eBean then EbeanServer provides additional methods where you 075 * can explicitly pass a transaction (that can be created externally). 076 * </p> 077 * <p> 078 * <em>Bypass ThreadLocal Mechanism:</em> If you want to bypass the built in 079 * ThreadLocal transaction management you can use the createTransaction() 080 * method. Example: a single thread requires more than one transaction. 081 * </p> 082 * 083 * @see Ebean 084 * @see EbeanServerFactory 085 * @see ServerConfig 086 */ 087public interface EbeanServer { 088 089 /** 090 * Shutdown the EbeanServer programmatically. 091 * <p> 092 * This method is not normally required. Ebean registers a shutdown hook and shuts down cleanly. 093 * </p> 094 * <p> 095 * If the under underlying DataSource is the Ebean implementation then you 096 * also have the option of shutting down the DataSource and deregistering the 097 * JDBC driver. 098 * </p> 099 * 100 * @param shutdownDataSource 101 * if true then shutdown the underlying DataSource if it is the EbeanORM 102 * DataSource implementation. 103 * @param deregisterDriver 104 * if true then deregister the JDBC driver if it is the EbeanORM 105 * DataSource implementation. 106 */ 107 void shutdown(boolean shutdownDataSource, boolean deregisterDriver); 108 109 /** 110 * Return AutoTune which is used to control the AutoTune service at runtime. 111 */ 112 AutoTune getAutoTune(); 113 114 /** 115 * Return the name. This is used with {@link Ebean#getServer(String)} to get a 116 * EbeanServer that was registered with the Ebean singleton. 117 */ 118 String getName(); 119 120 /** 121 * Return the ExpressionFactory for this server. 122 */ 123 ExpressionFactory getExpressionFactory(); 124 125 /** 126 * Return the MetaInfoManager which is used to get meta data from the EbeanServer 127 * such as query execution statistics. 128 */ 129 MetaInfoManager getMetaInfoManager(); 130 131 /** 132 * Return the extended API intended for use by plugins. 133 */ 134 SpiServer getPluginApi(); 135 136 /** 137 * Return the BeanState for a given entity bean. 138 * <p> 139 * This will return null if the bean is not an enhanced entity bean. 140 * </p> 141 */ 142 BeanState getBeanState(Object bean); 143 144 /** 145 * Return the value of the Id property for a given bean. 146 */ 147 Object getBeanId(Object bean); 148 149 /** 150 * Return a map of the differences between two objects of the same type. 151 * <p> 152 * When null is passed in for b, then the 'OldValues' of a is used for the 153 * difference comparison. 154 * </p> 155 */ 156 Map<String, ValuePair> diff(Object newBean, Object oldBean); 157 158 /** 159 * Create a new instance of T that is an EntityBean. 160 * <p> 161 * Generally not expected to be useful (now dynamic subclassing support was removed in 162 * favour of always using enhancement). 163 * </p> 164 */ 165 <T> T createEntityBean(Class<T> type); 166 167 /** 168 * Create a CsvReader for a given beanType. 169 */ 170 <T> CsvReader<T> createCsvReader(Class<T> beanType); 171 172 /** 173 * Return a named Query that will have defined fetch paths, predicates etc. 174 * <p> 175 * The query is created from a statement that will be defined in a deployment 176 * orm xml file or NamedQuery annotations. The query will typically already 177 * define fetch paths, predicates, order by clauses etc so often you will just 178 * need to bind required parameters and then execute the query. 179 * </p> 180 * 181 * <pre>{@code 182 * 183 * // example 184 * Query<Order> query = ebeanServer.createNamedQuery(Order.class, "new.for.customer"); 185 * query.setParameter("customerId", 23); 186 * List<Order> newOrders = query.findList(); 187 * 188 * }</pre> 189 */ 190 <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery); 191 192 /** 193 * Create a query using the query language. 194 * <p> 195 * Note that you are allowed to add additional clauses using where() as well 196 * as use fetch() and setOrderBy() after the query has been created. 197 * </p> 198 * <p> 199 * Note that this method signature used to map to named queries and that has 200 * moved to {@link #createNamedQuery(Class, String)}. 201 * </p> 202 * 203 * <pre>{@code 204 * EbeanServer ebeanServer = ... ; 205 * String q = "find order fetch details where status = :st"; 206 * 207 * List<Order> newOrders 208 * = ebeanServer.createQuery(Order.class, q) 209 * .setParameter("st", Order.Status.NEW) 210 * .findList(); 211 * }</pre> 212 * 213 * @param query 214 * the object query 215 */ 216 <T> Query<T> createQuery(Class<T> beanType, String query); 217 218 /** 219 * Create a query for an entity bean and synonym for {@link #find(Class)}. 220 * 221 * @see #find(Class) 222 */ 223 <T> Query<T> createQuery(Class<T> beanType); 224 225 /** 226 * Create a query for a type of entity bean. 227 * <p> 228 * You can use the methods on the Query object to specify fetch paths, 229 * predicates, order by, limits etc. 230 * </p> 231 * <p> 232 * You then use findList(), findSet(), findMap() and findUnique() to execute 233 * the query and return the collection or bean. 234 * </p> 235 * <p> 236 * Note that a query executed by {@link Query#findList()} 237 * {@link Query#findSet()} etc will execute against the same EbeanServer from 238 * which is was created. 239 * </p> 240 * 241 * <pre>{@code 242 * 243 * // Find order 2 specifying explicitly the parts of the object graph to 244 * // eagerly fetch. In this case eagerly fetch the associated customer, 245 * // details and details.product.name 246 * 247 * Order order = ebeanServer.find(Order.class) 248 * .fetch("customer") 249 * .fetch("details") 250 * .fetch("detail.product", "name") 251 * .setId(2) 252 * .findUnique(); 253 * 254 * // find some new orders ... with firstRow/maxRows 255 * List<Order> orders = 256 * ebeanServer.find(Order.class) 257 * .where().eq("status", Order.Status.NEW) 258 * .setFirstRow(20) 259 * .setMaxRows(10) 260 * .findList(); 261 * 262 * }</pre> 263 * 264 */ 265 <T> Query<T> find(Class<T> beanType); 266 267 /** 268 * Return the next unique identity value for a given bean type. 269 * <p> 270 * This will only work when a IdGenerator is on the bean such as for beans 271 * that use a DB sequence or UUID. 272 * </p> 273 * <p> 274 * For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do 275 * not need to use this method generally. It is made available for more 276 * complex cases where it is useful to get an ID prior to some processing. 277 * </p> 278 */ 279 Object nextId(Class<?> beanType); 280 281 /** 282 * Create a filter for sorting and filtering lists of entities locally without 283 * going back to the database. 284 * <p> 285 * This produces and returns a new list with the sort and filters applied. 286 * </p> 287 * <p> 288 * Refer to {@link Filter} for an example of its use. 289 * </p> 290 */ 291 <T> Filter<T> filter(Class<T> beanType); 292 293 /** 294 * Sort the list in memory using the sortByClause which can contain a comma delimited 295 * list of property names and keywords asc, desc, nullsHigh and nullsLow. 296 * <ul> 297 * <li>asc - ascending order (which is the default)</li> 298 * <li>desc - Descending order</li> 299 * <li>nullsHigh - Treat null values as high/large values (which is the 300 * default)</li> 301 * <li>nullsLow- Treat null values as low/very small values</li> 302 * </ul> 303 * <p> 304 * If you leave off any keywords the defaults are ascending order and treating 305 * nulls as high values. 306 * </p> 307 * <p> 308 * Note that the sorting uses a Comparator and Collections.sort(); and does 309 * not invoke a DB query. 310 * </p> 311 * 312 * <pre>{@code 313 * 314 * // find orders and their customers 315 * List<Order> list = ebeanServer.find(Order.class) 316 * .fetch("customer") 317 * .orderBy("id") 318 * .findList(); 319 * 320 * // sort by customer name ascending, then by order shipDate 321 * // ... then by the order status descending 322 * ebeanServer.sort(list, "customer.name, shipDate, status desc"); 323 * 324 * // sort by customer name descending (with nulls low) 325 * // ... then by the order id 326 * ebeanServer.sort(list, "customer.name desc nullsLow, id"); 327 * 328 * }</pre> 329 * 330 * @param list 331 * the list of entity beans 332 * @param sortByClause 333 * the properties to sort the list by 334 */ 335 <T> void sort(List<T> list, String sortByClause); 336 337 /** 338 * Create a named orm update. The update statement is specified via the 339 * NamedUpdate annotation. 340 * <p> 341 * The orm update differs from the SqlUpdate in that it uses the bean name and 342 * bean property names rather than table and column names. 343 * </p> 344 * <p> 345 * Note that named update statements can be specified in raw sql (with column 346 * and table names) or using bean name and bean property names. This can be 347 * specified with the isSql flag. 348 * </p> 349 * <p> 350 * Example named updates: 351 * </p> 352 * 353 * <pre>{@code 354 * package app.data; 355 * 356 * import ... 357 * 358 * @NamedUpdates(value = { 359 * @NamedUpdate( name = "setTitle", 360 * isSql = false, 361 * notifyCache = false, 362 * update = "update topic set title = :title, postCount = :postCount where id = :id"), 363 * @NamedUpdate( name = "setPostCount", 364 * notifyCache = false, 365 * update = "update f_topic set post_count = :postCount where id = :id"), 366 * @NamedUpdate( name = "incrementPostCount", 367 * notifyCache = false, 368 * isSql = false, 369 * update = "update Topic set postCount = postCount + 1 where id = :id") }) 370 * @Entity 371 * @Table(name = "f_topic") 372 * public class Topic { ... 373 * 374 * }</pre> 375 * 376 * <p> 377 * Example using a named update: 378 * </p> 379 * 380 * <pre>{@code 381 * 382 * Update<Topic> update = ebeanServer.createNamedUpdate(Topic.class, "setPostCount"); 383 * update.setParameter("postCount", 10); 384 * update.setParameter("id", 3); 385 * 386 * int rows = update.execute(); 387 * System.out.println("rows updated: " + rows); 388 * 389 * }</pre> 390 */ 391 <T> Update<T> createNamedUpdate(Class<T> beanType, String namedUpdate); 392 393 /** 394 * Create a orm update where you will supply the insert/update or delete 395 * statement (rather than using a named one that is already defined using the 396 * @NamedUpdates annotation). 397 * <p> 398 * The orm update differs from the sql update in that it you can use the bean 399 * name and bean property names rather than table and column names. 400 * </p> 401 * <p> 402 * An example: 403 * </p> 404 * 405 * <pre>{@code 406 * 407 * // The bean name and properties - "topic","postCount" and "id" 408 * 409 * // will be converted into their associated table and column names 410 * String updStatement = "update topic set postCount = :pc where id = :id"; 411 * 412 * Update<Topic> update = ebeanServer.createUpdate(Topic.class, updStatement); 413 * 414 * update.set("pc", 9); 415 * update.set("id", 3); 416 * 417 * int rows = update.execute(); 418 * System.out.println("rows updated:" + rows); 419 * 420 * }</pre> 421 */ 422 <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate); 423 424 /** 425 * Create a SqlQuery for executing native sql 426 * query statements. 427 * <p> 428 * Note that you can use raw SQL with entity beans, refer to the SqlSelect 429 * annotation for examples. 430 * </p> 431 */ 432 SqlQuery createSqlQuery(String sql); 433 434 /** 435 * Create a named sql query. 436 * <p> 437 * The query statement will be defined in a deployment orm xml file. 438 * </p> 439 * 440 * @param namedQuery 441 * the name of the query 442 */ 443 SqlQuery createNamedSqlQuery(String namedQuery); 444 445 /** 446 * Create a sql update for executing native dml statements. 447 * <p> 448 * Use this to execute a Insert Update or Delete statement. The statement will 449 * be native to the database and contain database table and column names. 450 * </p> 451 * <p> 452 * See {@link SqlUpdate} for example usage. 453 * </p> 454 * <p> 455 * Where possible it would be expected practice to put the statement in a orm 456 * xml file (named update) and use {@link #createNamedSqlUpdate(String)} . 457 * </p> 458 */ 459 SqlUpdate createSqlUpdate(String sql); 460 461 /** 462 * Create a CallableSql to execute a given stored procedure. 463 */ 464 CallableSql createCallableSql(String callableSql); 465 466 /** 467 * Create a named sql update. 468 * <p> 469 * The statement (an Insert Update or Delete statement) will be defined in a 470 * deployment orm xml file. 471 * </p> 472 * 473 * <pre>{@code 474 * 475 * // Use a namedQuery 476 * UpdateSql update = Ebean.createNamedSqlUpdate("update.topic.count"); 477 * 478 * update.setParameter("count", 1); 479 * update.setParameter("topicId", 50); 480 * 481 * int modifiedCount = update.execute(); 482 * 483 * }</pre> 484 */ 485 SqlUpdate createNamedSqlUpdate(String namedQuery); 486 487 /** 488 * Register a TransactionCallback on the currently active transaction. 489 * <p/> 490 * If there is no currently active transaction then a PersistenceException is thrown. 491 * 492 * @param transactionCallback The transaction callback to be registered with the current transaction. 493 * 494 * @throws PersistenceException If there is no currently active transaction 495 */ 496 void register(TransactionCallback transactionCallback) throws PersistenceException; 497 498 /** 499 * Create a new transaction that is not held in TransactionThreadLocal. 500 * <p> 501 * You will want to do this if you want multiple Transactions in a single 502 * thread or generally use transactions outside of the TransactionThreadLocal 503 * management. 504 * </p> 505 */ 506 Transaction createTransaction(); 507 508 /** 509 * Create a new transaction additionally specifying the isolation level. 510 * <p> 511 * Note that this transaction is NOT stored in a thread local. 512 * </p> 513 */ 514 Transaction createTransaction(TxIsolation isolation); 515 516 /** 517 * Start a transaction with 'REQUIRED' semantics. 518 * <p> 519 * With REQUIRED semantics if an active transaction already exists that transaction will be used. 520 * </p> 521 * <p> 522 * The transaction is stored in a ThreadLocal variable and typically you only 523 * need to use the returned Transaction <em>IF</em> you wish to do things like 524 * use batch mode, change the transaction isolation level, use savepoints or 525 * log comments to the transaction log. 526 * </p> 527 * <p> 528 * Example of using a transaction to span multiple calls to find(), save() 529 * etc. 530 * </p> 531 * 532 * <pre>{@code 533 * 534 * // start a transaction (stored in a ThreadLocal) 535 * ebeanServer.beginTransaction(); 536 * try { 537 * Order order = ebeanServer.find(Order.class,10); 538 * 539 * ebeanServer.save(order); 540 * 541 * ebeanServer.commitTransaction(); 542 * 543 * } finally { 544 * // rollback if we didn't commit 545 * // i.e. an exception occurred before commitTransaction(). 546 * ebeanServer.endTransaction(); 547 * } 548 * 549 * }</pre> 550 * 551 * <h3>Transaction options:</h3> 552 * <pre>{@code 553 * 554 * Transaction txn = ebeanServer.beginTransaction(); 555 * try { 556 * // explicitly turn on/off JDBC batch use 557 * txn.setBatchMode(true); 558 * txn.setBatchSize(50); 559 * 560 * // control flushing when mixing save and queries 561 * txn.setBatchFlushOnQuery(false); 562 * 563 * // turn off persist cascade if needed 564 * txn.setPersistCascade(false); 565 * 566 * // for large batch insert processing when we do not 567 * // ... need the generatedKeys, don't get them 568 * txn.setBatchGetGeneratedKeys(false); 569 * 570 * // explicitly flush the JDBC batch buffer 571 * txn.flushBatch(); 572 * 573 * ... 574 * 575 * txn.commit(); 576 * 577 * } finally { 578 * // rollback if necessary 579 * txn.end(); 580 * } 581 * 582 * }</pre> 583 * 584 * <p> 585 * If you want to externalise the transaction management then you use 586 * createTransaction() and pass the transaction around to the various methods on 587 * EbeanServer yourself. 588 * </p> 589 */ 590 Transaction beginTransaction(); 591 592 /** 593 * Start a transaction additionally specifying the isolation level. 594 */ 595 Transaction beginTransaction(TxIsolation isolation); 596 597 /** 598 * Start a transaction typically specifying REQUIRES_NEW or REQUIRED semantics. 599 * 600 * <p> 601 * Note that this provides an try finally alternative to using {@link #execute(TxScope, TxCallable)} or 602 * {@link #execute(TxScope, TxRunnable)}. 603 * </p> 604 * 605 * <h3>REQUIRES_NEW example:</h3> 606 * <pre>{@code 607 * // Start a new transaction. If there is a current transaction 608 * // suspend it until this transaction ends 609 * Transaction txn = server.beginTransaction(TxScope.requiresNew()); 610 * try { 611 * 612 * ... 613 * 614 * // commit the transaction 615 * txn.commit(); 616 * 617 * } finally { 618 * // end this transaction which: 619 * // A) will rollback transaction if it has not been committed already 620 * // B) will restore a previously suspended transaction 621 * txn.end(); 622 * } 623 * 624 * }</pre> 625 * 626 * <h3>REQUIRED example:</h3> 627 * <pre>{@code 628 * 629 * // start a new transaction if there is not a current transaction 630 * Transaction txn = server.beginTransaction(TxScope.required()); 631 * try { 632 * 633 * ... 634 * 635 * // commit the transaction if it was created or 636 * // do nothing if there was already a current transaction 637 * txn.commit(); 638 * 639 * } finally { 640 * // end this transaction which will rollback the transaction 641 * // if it was created for this try finally scope and has not 642 * // already been committed 643 * txn.end(); 644 * } 645 * 646 * }</pre> 647 */ 648 Transaction beginTransaction(TxScope scope); 649 650 /** 651 * Returns the current transaction or null if there is no current transaction in scope. 652 */ 653 Transaction currentTransaction(); 654 655 /** 656 * Commit the current transaction. 657 */ 658 void commitTransaction(); 659 660 /** 661 * Rollback the current transaction. 662 */ 663 void rollbackTransaction(); 664 665 /** 666 * If the current transaction has already been committed do nothing otherwise 667 * rollback the transaction. 668 * <p> 669 * Useful to put in a finally block to ensure the transaction is ended, rather 670 * than a rollbackTransaction() in each catch block. 671 * </p> 672 * <p> 673 * Code example: 674 * 675 * <pre>{@code 676 * 677 * ebeanServer.beginTransaction(); 678 * try { 679 * // do some fetching and or persisting ... 680 * 681 * // commit at the end 682 * ebeanServer.commitTransaction(); 683 * 684 * } finally { 685 * // if commit didn't occur then rollback the transaction 686 * ebeanServer.endTransaction(); 687 * } 688 * 689 * }</pre> 690 * 691 * </p> 692 * 693 */ 694 void endTransaction(); 695 696 /** 697 * Refresh the values of a bean. 698 * <p> 699 * Note that this resets OneToMany and ManyToMany properties so that if they 700 * are accessed a lazy load will refresh the many property. 701 * </p> 702 */ 703 void refresh(Object bean); 704 705 /** 706 * Refresh a many property of an entity bean. 707 * 708 * @param bean 709 * the entity bean containing the 'many' property 710 * @param propertyName 711 * the 'many' property to be refreshed 712 * 713 */ 714 void refreshMany(Object bean, String propertyName); 715 716 /** 717 * Find a bean using its unique id. 718 * 719 * <pre>{@code 720 * // Fetch order 1 721 * Order order = ebeanServer.find(Order.class, 1); 722 * }</pre> 723 * 724 * <p> 725 * If you want more control over the query then you can use createQuery() and 726 * Query.findUnique(); 727 * </p> 728 * 729 * <pre>{@code 730 * // ... additionally fetching customer, customer shipping address, 731 * // order details, and the product associated with each order detail. 732 * // note: only product id and name is fetch (its a "partial object"). 733 * // note: all other objects use "*" and have all their properties fetched. 734 * 735 * Query<Order> query = ebeanServer.find(Order.class) 736 * .setId(1) 737 * .fetch("customer") 738 * .fetch("customer.shippingAddress") 739 * .fetch("details") 740 * .query(); 741 * 742 * // fetch associated products but only fetch their product id and name 743 * query.fetch("details.product", "name"); 744 * 745 * 746 * Order order = query.findUnique(); 747 * 748 * // traverse the object graph... 749 * 750 * Customer customer = order.getCustomer(); 751 * Address shippingAddress = customer.getShippingAddress(); 752 * List<OrderDetail> details = order.getDetails(); 753 * OrderDetail detail0 = details.get(0); 754 * Product product = detail0.getProduct(); 755 * String productName = product.getName(); 756 * 757 * }</pre> 758 * 759 * @param beanType 760 * the type of entity bean to fetch 761 * @param id 762 * the id value 763 */ 764 <T> T find(Class<T> beanType, Object id); 765 766 /** 767 * Get a reference object. 768 * <p> 769 * This will not perform a query against the database unless some property other 770 * that the id property is accessed. 771 * </p> 772 * <p> 773 * It is most commonly used to set a 'foreign key' on another bean like: 774 * </p> 775 * <pre>{@code 776 * 777 * Product product = ebeanServer.getReference(Product.class, 1); 778 * 779 * OrderDetail orderDetail = new OrderDetail(); 780 * // set the product 'foreign key' 781 * orderDetail.setProduct(product); 782 * orderDetail.setQuantity(42); 783 * ... 784 * 785 * ebeanServer.save(orderDetail); 786 * 787 * 788 * }</pre> 789 * 790 * <h3>Lazy loading characteristics</h3> 791 * <pre>{@code 792 * 793 * Product product = ebeanServer.getReference(Product.class, 1); 794 * 795 * // You can get the id without causing a fetch/lazy load 796 * Long productId = product.getId(); 797 * 798 * // If you try to get any other property a fetch/lazy loading will occur 799 * // This will cause a query to execute... 800 * String name = product.getName(); 801 * 802 * }</pre> 803 * 804 * @param beanType 805 * the type of entity bean 806 * @param id 807 * the id value 808 */ 809 <T> T getReference(Class<T> beanType, Object id); 810 811 /** 812 * Return the number of 'top level' or 'root' entities this query should 813 * return. 814 * 815 * @see Query#findRowCount() 816 * @see com.avaje.ebean.Query#findFutureRowCount() 817 */ 818 <T> int findRowCount(Query<T> query, Transaction transaction); 819 820 /** 821 * Return the Id values of the query as a List. 822 * 823 * @see com.avaje.ebean.Query#findIds() 824 */ 825 <T> List<Object> findIds(Query<T> query, Transaction transaction); 826 827 /** 828 * Return a QueryIterator for the query. 829 * <p> 830 * Generally using {@link #findEach(Query, QueryEachConsumer, Transaction)} or 831 * {@link #findEachWhile(Query, QueryEachWhileConsumer, Transaction)} is preferred 832 * to findIterate(). The reason is that those methods automatically take care of 833 * closing the queryIterator (and the underlying jdbc statement and resultSet). 834 * </p> 835 * <p> 836 * This is similar to findEach in that not all the result beans need to be held 837 * in memory at the same time and as such is good for processing large queries. 838 * </p> 839 * 840 * @see Query#findEach(QueryEachConsumer) 841 * @see Query#findEachWhile(QueryEachWhileConsumer) 842 */ 843 <T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction); 844 845 /** 846 * Execute the query visiting the each bean one at a time. 847 * <p> 848 * Unlike findList() this is suitable for processing a query that will return 849 * a very large resultSet. The reason is that not all the result beans need to be 850 * held in memory at the same time and instead processed one at a time. 851 * </p> 852 * <p> 853 * Internally this query using a PersistenceContext scoped to each bean (and the 854 * beans associated object graph). 855 * </p> 856 * 857 * <pre>{@code 858 * 859 * ebeanServer.find(Order.class) 860 * .where().eq("status", Order.Status.NEW) 861 * .order().asc("id") 862 * .findEach((Order order) -> { 863 * 864 * // do something with the order bean 865 * System.out.println(" -- processing order ... " + order); 866 * }); 867 * 868 * }</pre> 869 * 870 * @see Query#findEach(QueryEachConsumer) 871 * @see Query#findEachWhile(QueryEachWhileConsumer) 872 */ 873 <T> void findEach(Query<T> query, QueryEachConsumer<T> consumer, Transaction transaction); 874 875 /** 876 * Execute the query visiting the each bean one at a time. 877 * <p> 878 * Compared to findEach() this provides the ability to stop processing the query 879 * results early by returning false for the QueryEachWhileConsumer. 880 * </p> 881 * <p> 882 * Unlike findList() this is suitable for processing a query that will return 883 * a very large resultSet. The reason is that not all the result beans need to be 884 * held in memory at the same time and instead processed one at a time. 885 * </p> 886 * <p> 887 * Internally this query using a PersistenceContext scoped to each bean (and the 888 * beans associated object graph). 889 * </p> 890 * 891 * <pre>{@code 892 * 893 * ebeanServer.find(Order.class) 894 * .where().eq("status", Order.Status.NEW) 895 * .order().asc("id") 896 * .findEachWhile((Order order) -> { 897 * 898 * // do something with the order bean 899 * System.out.println(" -- processing order ... " + order); 900 * 901 * boolean carryOnProcessing = ... 902 * return carryOnProcessing; 903 * }); 904 * 905 * }</pre> 906 * 907 * @see Query#findEach(QueryEachConsumer) 908 * @see Query#findEachWhile(QueryEachWhileConsumer) 909 */ 910 <T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction transaction); 911 912 /** 913 * Return versions of a @History entity bean. 914 * <p> 915 * Generally this query is expected to be a find by id or unique predicates query. 916 * It will execute the query against the history returning the versions of the bean. 917 * </p> 918 */ 919 <T> List<Version<T>> findVersions(Query<T> query, Transaction transaction); 920 921 /** 922 * Execute a query returning a list of beans. 923 * <p> 924 * Generally you are able to use {@link Query#findList()} rather than 925 * explicitly calling this method. You could use this method if you wish to 926 * explicitly control the transaction used for the query. 927 * </p> 928 * 929 * <pre>{@code 930 * 931 * List<Customer> customers = 932 * ebeanServer.find(Customer.class) 933 * .where().ilike("name", "rob%") 934 * .findList(); 935 * 936 * }</pre> 937 * 938 * @param <T> 939 * the type of entity bean to fetch. 940 * @param query 941 * the query to execute. 942 * @param transaction 943 * the transaction to use (can be null). 944 * @return the list of fetched beans. 945 * 946 * @see Query#findList() 947 */ 948 <T> List<T> findList(Query<T> query, Transaction transaction); 949 950 /** 951 * Execute find row count query in a background thread. 952 * <p> 953 * This returns a Future object which can be used to cancel, check the 954 * execution status (isDone etc) and get the value (with or without a 955 * timeout). 956 * </p> 957 * 958 * @param query 959 * the query to execute the row count on 960 * @param transaction 961 * the transaction (can be null). 962 * @return a Future object for the row count query 963 * 964 * @see com.avaje.ebean.Query#findFutureRowCount() 965 */ 966 <T> FutureRowCount<T> findFutureRowCount(Query<T> query, Transaction transaction); 967 968 /** 969 * Execute find Id's query in a background thread. 970 * <p> 971 * This returns a Future object which can be used to cancel, check the 972 * execution status (isDone etc) and get the value (with or without a 973 * timeout). 974 * </p> 975 * 976 * @param query 977 * the query to execute the fetch Id's on 978 * @param transaction 979 * the transaction (can be null). 980 * @return a Future object for the list of Id's 981 * 982 * @see com.avaje.ebean.Query#findFutureIds() 983 */ 984 <T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction); 985 986 /** 987 * Execute find list query in a background thread returning a FutureList object. 988 * <p> 989 * This returns a Future object which can be used to cancel, check the 990 * execution status (isDone etc) and get the value (with or without a timeout). 991 * <p> 992 * This query will execute in it's own PersistenceContext and using its own transaction. 993 * What that means is that it will not share any bean instances with other queries. 994 * 995 * 996 * @param query 997 * the query to execute in the background 998 * @param transaction 999 * the transaction (can be null). 1000 * @return a Future object for the list result of the query 1001 * 1002 * @see Query#findFutureList() 1003 */ 1004 <T> FutureList<T> findFutureList(Query<T> query, Transaction transaction); 1005 1006 /** 1007 * Execute find list SQL query in a background thread. 1008 * <p> 1009 * This returns a Future object which can be used to cancel, check the 1010 * execution status (isDone etc) and get the value (with or without a 1011 * timeout). 1012 * </p> 1013 * 1014 * @param query 1015 * the query to execute in the background 1016 * @param transaction 1017 * the transaction (can be null). 1018 * @return a Future object for the list result of the query 1019 */ 1020 SqlFutureList findFutureList(SqlQuery query, Transaction transaction); 1021 1022 /** 1023 * Return a PagedList for this query using pageIndex and pageSize. 1024 * <p> 1025 * The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and 1026 * {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to 1027 * {@link Query#findFutureRowCount()} to determine total row count, total page count etc. 1028 * </p> 1029 * <p> 1030 * Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on 1031 * the query. This translates into SQL that uses limit offset, rownum or row_number 1032 * function to limit the result set. 1033 * </p> 1034 * 1035 * @param pageIndex 1036 * The zero based index of the page. 1037 * @param pageSize 1038 * The number of beans to return per page. 1039 * @return The PagedList 1040 * 1041 * @see Query#findPagedList(int, int) 1042 */ 1043 <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction, int pageIndex, int pageSize); 1044 1045 /** 1046 * Return a PagedList for this query using firstRow and maxRows. 1047 * <p> 1048 * The benefit of using this over findList() is that it provides functionality to get the 1049 * total row count etc. 1050 * </p> 1051 * <p> 1052 * If maxRows is not set on the query prior to calling findPagedList() then a 1053 * PersistenceException is thrown. 1054 * </p> 1055 * 1056 * <pre>{@code 1057 * 1058 * PagedList<Order> pagedList = Ebean.find(Order.class) 1059 * .setFirstRow(50) 1060 * .setMaxRows(20) 1061 * .findPagedList(); 1062 * 1063 * // fetch the total row count in the background 1064 * pagedList.loadRowCount(); 1065 * 1066 * List<Order> orders = pagedList.getList(); 1067 * int totalRowCount = pagedList.getTotalRowCount(); 1068 * 1069 * }</pre> 1070 * 1071 * @return The PagedList 1072 * 1073 * @see Query#findPagedList() 1074 */ 1075 <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction); 1076 1077 /** 1078 * Execute the query returning a set of entity beans. 1079 * <p> 1080 * Generally you are able to use {@link Query#findSet()} rather than 1081 * explicitly calling this method. You could use this method if you wish to 1082 * explicitly control the transaction used for the query. 1083 * </p> 1084 * 1085 * <pre>{@code 1086 * 1087 * Set<Customer> customers = 1088 * ebeanServer.find(Customer.class) 1089 * .where().ilike("name", "rob%") 1090 * .findSet(); 1091 * 1092 * }</pre> 1093 * 1094 * @param <T> 1095 * the type of entity bean to fetch. 1096 * @param query 1097 * the query to execute 1098 * @param transaction 1099 * the transaction to use (can be null). 1100 * @return the set of fetched beans. 1101 * 1102 * @see Query#findSet() 1103 */ 1104 <T> Set<T> findSet(Query<T> query, Transaction transaction); 1105 1106 /** 1107 * Execute the query returning the entity beans in a Map. 1108 * <p> 1109 * Generally you are able to use {@link Query#findMap()} rather than 1110 * explicitly calling this method. You could use this method if you wish to 1111 * explicitly control the transaction used for the query. 1112 * </p> 1113 * 1114 * @param <T> 1115 * the type of entity bean to fetch. 1116 * @param query 1117 * the query to execute. 1118 * @param transaction 1119 * the transaction to use (can be null). 1120 * @return the map of fetched beans. 1121 * 1122 * @see Query#findMap() 1123 */ 1124 <T> Map<?, T> findMap(Query<T> query, Transaction transaction); 1125 1126 /** 1127 * Execute the query returning at most one entity bean or null (if no matching 1128 * bean is found). 1129 * <p> 1130 * This will throw a NonUniqueResultException if the query finds more than one result. 1131 * </p> 1132 * <p> 1133 * Generally you are able to use {@link Query#findUnique()} rather than 1134 * explicitly calling this method. You could use this method if you wish to 1135 * explicitly control the transaction used for the query. 1136 * </p> 1137 * 1138 * @param <T> 1139 * the type of entity bean to fetch. 1140 * @param query 1141 * the query to execute. 1142 * @param transaction 1143 * the transaction to use (can be null). 1144 * @return the list of fetched beans. 1145 * @throws NonUniqueResultException if more than one result was found 1146 * 1147 * @see Query#findUnique() 1148 */ 1149 @Nullable 1150 <T> T findUnique(Query<T> query, Transaction transaction); 1151 1152 /** 1153 * Execute as a delete query deleting the 'root level' beans that match the predicates 1154 * in the query. 1155 * <p> 1156 * Note that if the query includes joins then the generated delete statement may not be 1157 * optimal depending on the database platform. 1158 * </p> 1159 * 1160 * @param query the query used for the delete 1161 * @param transaction the transaction to use (can be null) 1162 * @param <T> the type of entity bean to fetch. 1163 * @return the number of beans/rows that were deleted 1164 */ 1165 <T> int delete(Query<T> query, Transaction transaction); 1166 1167 /** 1168 * Execute the sql query returning a list of MapBean. 1169 * <p> 1170 * Generally you are able to use {@link SqlQuery#findList()} rather than 1171 * explicitly calling this method. You could use this method if you wish to 1172 * explicitly control the transaction used for the query. 1173 * </p> 1174 * 1175 * @param query 1176 * the query to execute. 1177 * @param transaction 1178 * the transaction to use (can be null). 1179 * @return the list of fetched MapBean. 1180 * 1181 * @see SqlQuery#findList() 1182 */ 1183 List<SqlRow> findList(SqlQuery query, Transaction transaction); 1184 1185 /** 1186 * Execute the sql query returning a set of MapBean. 1187 * <p> 1188 * Generally you are able to use {@link SqlQuery#findSet()} rather than 1189 * explicitly calling this method. You could use this method if you wish to 1190 * explicitly control the transaction used for the query. 1191 * </p> 1192 * 1193 * @param query 1194 * the query to execute. 1195 * @param transaction 1196 * the transaction to use (can be null). 1197 * @return the set of fetched MapBean. 1198 * 1199 * @see SqlQuery#findSet() 1200 */ 1201 Set<SqlRow> findSet(SqlQuery query, Transaction transaction); 1202 1203 /** 1204 * Execute the sql query returning a map of MapBean. 1205 * <p> 1206 * Generally you are able to use {@link SqlQuery#findMap()} rather than 1207 * explicitly calling this method. You could use this method if you wish to 1208 * explicitly control the transaction used for the query. 1209 * </p> 1210 * 1211 * @param query 1212 * the query to execute. 1213 * @param transaction 1214 * the transaction to use (can be null). 1215 * @return the set of fetched MapBean. 1216 * 1217 * @see SqlQuery#findMap() 1218 */ 1219 Map<?, SqlRow> findMap(SqlQuery query, Transaction transaction); 1220 1221 /** 1222 * Execute the sql query returning a single MapBean or null. 1223 * <p> 1224 * This will throw a PersistenceException if the query found more than one 1225 * result. 1226 * </p> 1227 * <p> 1228 * Generally you are able to use {@link SqlQuery#findUnique()} rather than 1229 * explicitly calling this method. You could use this method if you wish to 1230 * explicitly control the transaction used for the query. 1231 * </p> 1232 * 1233 * @param query 1234 * the query to execute. 1235 * @param transaction 1236 * the transaction to use (can be null). 1237 * @return the fetched MapBean or null if none was found. 1238 * 1239 * @see SqlQuery#findUnique() 1240 */ 1241 @Nullable 1242 SqlRow findUnique(SqlQuery query, Transaction transaction); 1243 1244 /** 1245 * Either Insert or Update the bean depending on its state. 1246 * <p> 1247 * If there is no current transaction one will be created and committed for 1248 * you automatically. 1249 * </p> 1250 * <p> 1251 * Save can cascade along relationships. For this to happen you need to 1252 * specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the 1253 * OneToMany, OneToOne or ManyToMany annotation. 1254 * </p> 1255 * <p> 1256 * In this example below the details property has a CascadeType.ALL set so 1257 * saving an order will also save all its details. 1258 * </p> 1259 * 1260 * <pre>{@code 1261 * public class Order { ... 1262 * 1263 * @OneToMany(cascade=CascadeType.ALL, mappedBy="order") 1264 * List<OrderDetail> details; 1265 * ... 1266 * } 1267 * }</pre> 1268 * 1269 * <p> 1270 * When a save cascades via a OneToMany or ManyToMany Ebean will automatically 1271 * set the 'parent' object to the 'detail' object. In the example below in 1272 * saving the order and cascade saving the order details the 'parent' order 1273 * will be set against each order detail when it is saved. 1274 * </p> 1275 */ 1276 void save(Object bean) throws OptimisticLockException; 1277 1278 /** 1279 * Save all the beans in the collection. 1280 */ 1281 int saveAll(Collection<?> beans) throws OptimisticLockException; 1282 1283 /** 1284 * Delete the bean. 1285 * <p> 1286 * This will return true if the bean was deleted successfully or JDBC batch is being used. 1287 * </p> 1288 * <p> 1289 * If there is no current transaction one will be created and committed for 1290 * you automatically. 1291 * </p> 1292 * <p> 1293 * If the Bean does not have a version property (or loaded version property) and 1294 * the bean does not exist then this returns false indicating that nothing was 1295 * deleted. Note that, if JDBC batch mode is used then this always returns true. 1296 * </p> 1297 */ 1298 boolean delete(Object bean) throws OptimisticLockException; 1299 1300 /** 1301 * Delete the bean with an explicit transaction. 1302 * <p> 1303 * This will return true if the bean was deleted successfully or JDBC batch is being used. 1304 * </p> 1305 * <p> 1306 * If the Bean does not have a version property (or loaded version property) and 1307 * the bean does not exist then this returns false indicating that nothing was 1308 * deleted. However, if JDBC batch mode is used then this always returns true. 1309 * </p> 1310 */ 1311 boolean delete(Object bean, Transaction transaction) throws OptimisticLockException; 1312 1313 /** 1314 * Delete a bean permanently without soft delete. 1315 */ 1316 boolean deletePermanent(Object bean) throws OptimisticLockException; 1317 1318 /** 1319 * Delete a bean permanently without soft delete using an explicit transaction. 1320 */ 1321 boolean deletePermanent(Object bean, Transaction transaction) throws OptimisticLockException; 1322 1323 /** 1324 * Delete all the beans in the collection permanently without soft delete. 1325 */ 1326 int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException; 1327 1328 /** 1329 * Delete all the beans in the collection permanently without soft delete using an explicit transaction. 1330 */ 1331 int deleteAllPermanent(Collection<?> beans, Transaction transaction) throws OptimisticLockException; 1332 1333 /** 1334 * Delete the bean given its type and id. 1335 */ 1336 int delete(Class<?> beanType, Object id); 1337 1338 /** 1339 * Delete the bean given its type and id with an explicit transaction. 1340 */ 1341 int delete(Class<?> beanType, Object id, Transaction transaction); 1342 1343 /** 1344 * Delete all the beans in the collection. 1345 */ 1346 int deleteAll(Collection<?> beans) throws OptimisticLockException; 1347 1348 /** 1349 * Delete all the beans in the collection using an explicit transaction. 1350 */ 1351 int deleteAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException; 1352 1353 /** 1354 * Delete several beans given their type and id values. 1355 */ 1356 void deleteAll(Class<?> beanType, Collection<?> ids); 1357 1358 /** 1359 * Delete several beans given their type and id values with an explicit 1360 * transaction. 1361 */ 1362 void deleteAll(Class<?> beanType, Collection<?> ids, Transaction transaction); 1363 1364 /** 1365 * Execute a Sql Update Delete or Insert statement. This returns the number of 1366 * rows that where updated, deleted or inserted. If is executed in batch then 1367 * this returns -1. You can get the actual rowCount after commit() from 1368 * updateSql.getRowCount(). 1369 * <p> 1370 * If you wish to execute a Sql Select natively then you should use the 1371 * FindByNativeSql object. 1372 * </p> 1373 * <p> 1374 * Note that the table modification information is automatically deduced and 1375 * you do not need to call the Ebean.externalModification() method when you 1376 * use this method. 1377 * </p> 1378 * <p> 1379 * Example: 1380 * </p> 1381 * 1382 * <pre>{@code 1383 * 1384 * // example that uses 'named' parameters 1385 * String s = "UPDATE f_topic set post_count = :count where id = :id" 1386 * 1387 * SqlUpdate update = ebeanServer.createSqlUpdate(s); 1388 * 1389 * update.setParameter("id", 1); 1390 * update.setParameter("count", 50); 1391 * 1392 * int modifiedCount = ebeanServer.execute(update); 1393 * 1394 * String msg = "There where " + modifiedCount + "rows updated"; 1395 * 1396 * }</pre> 1397 * 1398 * @param sqlUpdate 1399 * the update sql potentially with bind values 1400 * 1401 * @return the number of rows updated or deleted. -1 if executed in batch. 1402 * 1403 * @see CallableSql 1404 */ 1405 int execute(SqlUpdate sqlUpdate); 1406 1407 /** 1408 * Execute a ORM insert update or delete statement using the current 1409 * transaction. 1410 * <p> 1411 * This returns the number of rows that where inserted, updated or deleted. 1412 * </p> 1413 */ 1414 int execute(Update<?> update); 1415 1416 /** 1417 * Execute a ORM insert update or delete statement with an explicit 1418 * transaction. 1419 */ 1420 int execute(Update<?> update, Transaction transaction); 1421 1422 /** 1423 * For making calls to stored procedures. 1424 * <p> 1425 * Example: 1426 * </p> 1427 * 1428 * <pre>{@code 1429 * 1430 * String sql = "{call sp_order_modify(?,?,?)}"; 1431 * 1432 * CallableSql cs = ebeanServer.createCallableSql(sql); 1433 * cs.setParameter(1, 27); 1434 * cs.setParameter(2, "SHIPPED"); 1435 * cs.registerOut(3, Types.INTEGER); 1436 * 1437 * ebeanServer.execute(cs); 1438 * 1439 * // read the out parameter 1440 * Integer returnValue = (Integer) cs.getObject(3); 1441 * 1442 * }</pre> 1443 * 1444 * @see CallableSql 1445 * @see Ebean#execute(SqlUpdate) 1446 */ 1447 int execute(CallableSql callableSql); 1448 1449 /** 1450 * Inform Ebean that tables have been modified externally. These could be the 1451 * result of from calling a stored procedure, other JDBC calls or external 1452 * programs including other frameworks. 1453 * <p> 1454 * If you use ebeanServer.execute(UpdateSql) then the table modification information 1455 * is automatically deduced and you do not need to call this method yourself. 1456 * </p> 1457 * <p> 1458 * This information is used to invalidate objects out of the cache and 1459 * potentially text indexes. This information is also automatically broadcast 1460 * across the cluster. 1461 * </p> 1462 * <p> 1463 * If there is a transaction then this information is placed into the current 1464 * transactions event information. When the transaction is committed this 1465 * information is registered (with the transaction manager). If this 1466 * transaction is rolled back then none of the transaction event information 1467 * registers including the information you put in via this method. 1468 * </p> 1469 * <p> 1470 * If there is NO current transaction when you call this method then this 1471 * information is registered immediately (with the transaction manager). 1472 * </p> 1473 * 1474 * @param tableName 1475 * the name of the table that was modified 1476 * @param inserted 1477 * true if rows where inserted into the table 1478 * @param updated 1479 * true if rows on the table where updated 1480 * @param deleted 1481 * true if rows on the table where deleted 1482 */ 1483 void externalModification(String tableName, boolean inserted, boolean updated, boolean deleted); 1484 1485 /** 1486 * Find a entity bean with an explicit transaction. 1487 * 1488 * @param <T> 1489 * the type of entity bean to find 1490 * @param beanType 1491 * the type of entity bean to find 1492 * @param id 1493 * the bean id value 1494 * @param transaction 1495 * the transaction to use (can be null) 1496 */ 1497 <T> T find(Class<T> beanType, Object id, Transaction transaction); 1498 1499 /** 1500 * Insert or update a bean with an explicit transaction. 1501 */ 1502 void save(Object bean, Transaction transaction) throws OptimisticLockException; 1503 1504 /** 1505 * Save all the beans in the collection with an explicit transaction. 1506 */ 1507 int saveAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException; 1508 1509 /** 1510 * Marks the entity bean as dirty. 1511 * <p> 1512 * This is used so that when a bean that is otherwise unmodified is updated the version 1513 * property is updated. 1514 * <p> 1515 * An unmodified bean that is saved or updated is normally skipped and this marks the bean as 1516 * dirty so that it is not skipped. 1517 * 1518 * <pre>{@code 1519 * 1520 * Customer customer = ebeanServer.find(Customer, id); 1521 * 1522 * // mark the bean as dirty so that a save() or update() will 1523 * // increment the version property 1524 * ebeanServer.markAsDirty(customer); 1525 * ebeanServer.save(customer); 1526 * 1527 * }</pre> 1528 */ 1529 void markAsDirty(Object bean); 1530 1531 /** 1532 * Saves the bean using an update. If you know you are updating a bean then it is preferable to 1533 * use this update() method rather than save(). 1534 * <p> 1535 * <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call 1536 * update().You can create a new instance and set some of its properties programmatically for via 1537 * JSON/XML marshalling etc. This is described as a 'stateless update'. 1538 * </p> 1539 * <p> 1540 * <b>Optimistic Locking: </b> Note that if the version property is not set when update() is 1541 * called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used). 1542 * </p> 1543 * <p> 1544 * <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a 1545 * OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children 1546 * that are in the database but are not in the collection are deleted. 1547 * </p> 1548 * <p> 1549 * <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting 1550 * controls if only the changed properties are included in the update or if all the loaded 1551 * properties are included instead. 1552 * </p> 1553 * 1554 * <pre>{@code 1555 * 1556 * // A 'stateless update' example 1557 * Customer customer = new Customer(); 1558 * customer.setId(7); 1559 * customer.setName("ModifiedNameNoOCC"); 1560 * ebeanServer.update(customer); 1561 * 1562 * }</pre> 1563 * 1564 * @see ServerConfig#setUpdatesDeleteMissingChildren(boolean) 1565 * @see ServerConfig#setUpdateChangesOnly(boolean) 1566 */ 1567 void update(Object bean) throws OptimisticLockException; 1568 1569 /** 1570 * Update a bean additionally specifying a transaction. 1571 */ 1572 void update(Object bean, Transaction transaction) throws OptimisticLockException; 1573 1574 /** 1575 * Update a bean additionally specifying a transaction and the deleteMissingChildren setting. 1576 * 1577 * @param bean 1578 * the bean to update 1579 * @param transaction 1580 * the transaction to use (can be null). 1581 * @param deleteMissingChildren 1582 * specify false if you do not want 'missing children' of a OneToMany 1583 * or ManyToMany to be automatically deleted. 1584 */ 1585 void update(Object bean, Transaction transaction, boolean deleteMissingChildren) throws OptimisticLockException; 1586 1587 /** 1588 * Update a collection of beans. If there is no current transaction one is created and used to 1589 * update all the beans in the collection. 1590 */ 1591 void updateAll(Collection<?> beans) throws OptimisticLockException; 1592 1593 /** 1594 * Update a collection of beans with an explicit transaction. 1595 */ 1596 void updateAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException; 1597 1598 /** 1599 * Insert the bean. 1600 * <p> 1601 * Compared to save() this forces bean to perform an insert rather than trying to decide 1602 * based on the bean state. As such this is useful when you fetch beans from one database 1603 * and want to insert them into another database (and you want to explicitly insert them). 1604 * </p> 1605 */ 1606 void insert(Object bean); 1607 1608 /** 1609 * Insert the bean with a transaction. 1610 */ 1611 void insert(Object bean, Transaction transaction); 1612 1613 /** 1614 * Insert a collection of beans. If there is no current transaction one is created and used to 1615 * insert all the beans in the collection. 1616 */ 1617 void insertAll(Collection<?> beans); 1618 1619 /** 1620 * Insert a collection of beans with an explicit transaction. 1621 */ 1622 void insertAll(Collection<?> beans, Transaction transaction); 1623 1624 /** 1625 * Delete the associations (from the intersection table) of a ManyToMany given 1626 * the owner bean and the propertyName of the ManyToMany collection. 1627 * <p> 1628 * Typically these deletions occur automatically when persisting a ManyToMany 1629 * collection and this provides a way to invoke those deletions directly. 1630 * </p> 1631 * 1632 * @return the number of associations deleted (from the intersection table). 1633 */ 1634 int deleteManyToManyAssociations(Object ownerBean, String propertyName); 1635 1636 /** 1637 * Delete the associations (from the intersection table) of a ManyToMany given 1638 * the owner bean and the propertyName of the ManyToMany collection. 1639 * <p> 1640 * Additionally specify a transaction to use. 1641 * </p> 1642 * <p> 1643 * Typically these deletions occur automatically when persisting a ManyToMany 1644 * collection and this provides a way to invoke those deletions directly. 1645 * </p> 1646 * 1647 * @return the number of associations deleted (from the intersection table). 1648 */ 1649 int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction); 1650 1651 /** 1652 * Save the associations of a ManyToMany given the owner bean and the 1653 * propertyName of the ManyToMany collection. 1654 * <p> 1655 * Typically the saving of these associations (inserting into the intersection 1656 * table) occurs automatically when persisting a ManyToMany. This provides a 1657 * way to invoke those insertions directly. 1658 * </p> 1659 */ 1660 void saveManyToManyAssociations(Object ownerBean, String propertyName); 1661 1662 /** 1663 * Save the associations of a ManyToMany given the owner bean and the 1664 * propertyName of the ManyToMany collection. 1665 * <p> 1666 * Typically the saving of these associations (inserting into the intersection 1667 * table) occurs automatically when persisting a ManyToMany. This provides a 1668 * way to invoke those insertions directly. 1669 * </p> 1670 */ 1671 void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction); 1672 1673 /** 1674 * Save the associated collection or bean given the property name. 1675 * <p> 1676 * This is similar to performing a save cascade on a specific property 1677 * manually. 1678 * </p> 1679 * <p> 1680 * Note that you can turn on/off cascading for a transaction via 1681 * {@link Transaction#setPersistCascade(boolean)} 1682 * </p> 1683 * 1684 * @param ownerBean 1685 * the bean instance holding the property we want to save 1686 * @param propertyName 1687 * the property we want to save 1688 */ 1689 void saveAssociation(Object ownerBean, String propertyName); 1690 1691 /** 1692 * Save the associated collection or bean given the property name with a 1693 * specific transaction. 1694 * <p> 1695 * This is similar to performing a save cascade on a specific property 1696 * manually. 1697 * </p> 1698 * <p> 1699 * Note that you can turn on/off cascading for a transaction via 1700 * {@link Transaction#setPersistCascade(boolean)} 1701 * </p> 1702 * 1703 * @param ownerBean 1704 * the bean instance holding the property we want to save 1705 * @param propertyName 1706 * the property we want to save 1707 */ 1708 void saveAssociation(Object ownerBean, String propertyName, Transaction transaction); 1709 1710 1711 /** 1712 * Execute explicitly passing a transaction. 1713 */ 1714 int execute(SqlUpdate updSql, Transaction transaction); 1715 1716 /** 1717 * Execute explicitly passing a transaction. 1718 */ 1719 int execute(CallableSql callableSql, Transaction transaction); 1720 1721 /** 1722 * Execute a TxRunnable in a Transaction with an explicit scope. 1723 * <p> 1724 * The scope can control the transaction type, isolation and rollback 1725 * semantics. 1726 * </p> 1727 * 1728 * <pre>{@code 1729 * 1730 * // set specific transactional scope settings 1731 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1732 * 1733 * ebeanServer.execute(scope, new TxRunnable() { 1734 * public void run() { 1735 * User u1 = Ebean.find(User.class, 1); 1736 * ... 1737 * } 1738 * }); 1739 * 1740 * }</pre> 1741 */ 1742 void execute(TxScope scope, TxRunnable runnable); 1743 1744 /** 1745 * Execute a TxRunnable in a Transaction with the default scope. 1746 * <p> 1747 * The default scope runs with REQUIRED and by default will rollback on any 1748 * exception (checked or runtime). 1749 * </p> 1750 * 1751 * <pre>{@code 1752 * 1753 * ebeanServer.execute(new TxRunnable() { 1754 * public void run() { 1755 * User u1 = ebeanServer.find(User.class, 1); 1756 * User u2 = ebeanServer.find(User.class, 2); 1757 * 1758 * u1.setName("u1 mod"); 1759 * u2.setName("u2 mod"); 1760 * 1761 * ebeanServer.save(u1); 1762 * ebeanServer.save(u2); 1763 * } 1764 * }); 1765 * 1766 * }</pre> 1767 */ 1768 void execute(TxRunnable runnable); 1769 1770 /** 1771 * Execute a TxCallable in a Transaction with an explicit scope. 1772 * <p> 1773 * The scope can control the transaction type, isolation and rollback 1774 * semantics. 1775 * </p> 1776 * 1777 * <pre>{@code 1778 * 1779 * // set specific transactional scope settings 1780 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1781 * 1782 * ebeanServer.execute(scope, new TxCallable<String>() { 1783 * public String call() { 1784 * User u1 = ebeanServer.find(User.class, 1); 1785 * ... 1786 * return u1.getEmail(); 1787 * } 1788 * }); 1789 * 1790 * }</pre> 1791 */ 1792 <T> T execute(TxScope scope, TxCallable<T> callable); 1793 1794 /** 1795 * Execute a TxCallable in a Transaction with the default scope. 1796 * <p> 1797 * The default scope runs with REQUIRED and by default will rollback on any 1798 * exception (checked or runtime). 1799 * </p> 1800 * <p> 1801 * This is basically the same as TxRunnable except that it returns an Object 1802 * (and you specify the return type via generics). 1803 * </p> 1804 * 1805 * <pre>{@code 1806 * 1807 * ebeanServer.execute(new TxCallable<String>() { 1808 * public String call() { 1809 * User u1 = ebeanServer.find(User.class, 1); 1810 * User u2 = ebeanServer.find(User.class, 2); 1811 * 1812 * u1.setName("u1 mod"); 1813 * u2.setName("u2 mod"); 1814 * 1815 * ebeanServer.save(u1); 1816 * ebeanServer.save(u2); 1817 * 1818 * return u1.getEmail(); 1819 * } 1820 * }); 1821 * 1822 * }</pre> 1823 */ 1824 <T> T execute(TxCallable<T> callable); 1825 1826 /** 1827 * Return the manager of the server cache ("L2" cache). 1828 * 1829 */ 1830 ServerCacheManager getServerCacheManager(); 1831 1832 /** 1833 * Return the BackgroundExecutor service for asynchronous processing of 1834 * queries. 1835 */ 1836 BackgroundExecutor getBackgroundExecutor(); 1837 1838 /** 1839 * Run the cache warming queries on all bean types that have one defined. 1840 * <p> 1841 * A cache warming query can be defined via {@link CacheStrategy}. 1842 * </p> 1843 */ 1844 void runCacheWarming(); 1845 1846 /** 1847 * Run the cache warming query for a specific bean type. 1848 * <p> 1849 * A cache warming query can be defined via {@link CacheStrategy}. 1850 * </p> 1851 */ 1852 void runCacheWarming(Class<?> beanType); 1853 1854 /** 1855 * Return the JsonContext for reading/writing JSON. 1856 * <p> 1857 * This instance is safe to be used concurrently by multiple threads and this 1858 * method is cheap to call. 1859 * </p> 1860 * 1861 * <h3>Simple example:</h3> 1862 * <pre>{@code 1863 * 1864 * JsonContext json = ebeanServer.json(); 1865 * String jsonOutput = json.toJson(list); 1866 * System.out.println(jsonOutput); 1867 * 1868 * }</pre> 1869 * 1870 * <h3>Using PathProperties:</h3> 1871 * <pre>{@code 1872 * 1873 * // specify just the properties we want 1874 * PathProperties paths = PathProperties.parse("name, status, anniversary"); 1875 * 1876 * List<Customer> customers = 1877 * ebeanServer.find(Customer.class) 1878 * // apply those paths to the query (only fetch what we need) 1879 * .apply(paths) 1880 * .where().ilike("name", "rob%") 1881 * .findList(); 1882 * 1883 * // ... get the json 1884 * JsonContext jsonContext = ebeanServer.json(); 1885 * String json = jsonContext.toJson(customers, paths); 1886 * 1887 * }</pre> 1888 * 1889 * @see com.avaje.ebean.text.PathProperties 1890 * @see Query#apply(com.avaje.ebean.text.PathProperties) 1891 */ 1892 JsonContext json(); 1893 1894 /** 1895 * Publish a single bean given its type and id returning the resulting live bean. 1896 * <p> 1897 * The values are published from the draft to the live bean. 1898 * </p> 1899 * 1900 * @param <T> the type of the entity bean 1901 * @param beanType the type of the entity bean 1902 * @param id the id of the entity bean 1903 * @param transaction the transaction the publish process should use (can be null) 1904 */ 1905 <T> T publish(Class<T> beanType, Object id, Transaction transaction); 1906 1907 /** 1908 * Publish a single bean given its type and id returning the resulting live bean. 1909 * This will use the current transaction or create one if required. 1910 * <p> 1911 * The values are published from the draft to the live bean. 1912 * </p> 1913 * 1914 * @param <T> the type of the entity bean 1915 * @param beanType the type of the entity bean 1916 * @param id the id of the entity bean 1917 */ 1918 <T> T publish(Class<T> beanType, Object id); 1919 1920 /** 1921 * Publish the beans that match the query returning the resulting published beans. 1922 * <p> 1923 * The values are published from the draft beans to the live beans. 1924 * </p> 1925 * 1926 * @param <T> the type of the entity bean 1927 * @param query the query used to select the draft beans to publish 1928 * @param transaction the transaction the publish process should use (can be null) 1929 */ 1930 <T> List<T> publish(Query<T> query, Transaction transaction); 1931 1932 /** 1933 * Publish the beans that match the query returning the resulting published beans. 1934 * This will use the current transaction or create one if required. 1935 * <p> 1936 * The values are published from the draft beans to the live beans. 1937 * </p> 1938 * 1939 * @param <T> the type of the entity bean 1940 * @param query the query used to select the draft beans to publish 1941 */ 1942 <T> List<T> publish(Query<T> query); 1943 1944 /** 1945 * Restore the draft bean back to the live state. 1946 * <p> 1947 * The values from the live beans are set back to the draft bean and the 1948 * <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset. 1949 * </p> 1950 * 1951 * @param <T> the type of the entity bean 1952 * @param beanType the type of the entity bean 1953 * @param id the id of the entity bean to restore 1954 * @param transaction the transaction the restore process should use (can be null) 1955 */ 1956 <T> T draftRestore(Class<T> beanType, Object id, Transaction transaction); 1957 1958 /** 1959 * Restore the draft bean back to the live state. 1960 * <p> 1961 * The values from the live beans are set back to the draft bean and the 1962 * <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset. 1963 * </p> 1964 * 1965 * @param <T> the type of the entity bean 1966 * @param beanType the type of the entity bean 1967 * @param id the id of the entity bean to restore 1968 */ 1969 <T> T draftRestore(Class<T> beanType, Object id); 1970 1971 /** 1972 * Restore the draft beans matching the query back to the live state. 1973 * <p> 1974 * The values from the live beans are set back to the draft bean and the 1975 * <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset. 1976 * </p> 1977 * 1978 * @param <T> the type of the entity bean 1979 * @param query the query used to select the draft beans to restore 1980 * @param transaction the transaction the restore process should use (can be null) 1981 */ 1982 <T> List<T> draftRestore(Query<T> query, Transaction transaction); 1983 1984 /** 1985 * Restore the draft beans matching the query back to the live state. 1986 * <p> 1987 * The values from the live beans are set back to the draft bean and the 1988 * <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset. 1989 * </p> 1990 * 1991 * @param <T> the type of the entity bean 1992 * @param query the query used to select the draft beans to restore 1993 */ 1994 <T> List<T> draftRestore(Query<T> query); 1995 1996 /** 1997 * Returns the set of properties/paths that are unknown (do not map to known properties or paths). 1998 * <p> 1999 * Validate the query checking the where and orderBy expression paths to confirm if 2000 * they represent valid properties/path for the given bean type. 2001 * </p> 2002 */ 2003 <T> Set<String> validateQuery(Query<T> query); 2004}