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