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