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