001package io.ebean; 002 003import io.avaje.lang.Nullable; 004import io.ebean.annotation.TxIsolation; 005import io.ebean.cache.ServerCacheManager; 006import io.ebean.plugin.Property; 007import io.ebean.text.csv.CsvReader; 008import io.ebean.text.json.JsonContext; 009 010import javax.persistence.OptimisticLockException; 011import javax.persistence.PersistenceException; 012import java.util.Collection; 013import java.util.List; 014import java.util.Map; 015import java.util.Set; 016import java.util.concurrent.Callable; 017 018/** 019 * Deprecated - please migrate to use <code>io.ebean.DB</code>. 020 * <p> 021 * Ebean is a registry of {@link Database} by name. Ebean has now been renamed to {@link DB}. 022 * <p> 023 * Ebean is effectively this is an alias for {@link DB} which is the new and improved name for Ebean. 024 * <p> 025 * The preference is to use DB and Database rather than Ebean and EbeanServer. 026 */ 027@Deprecated 028public final class Ebean { 029 030 private static final DbContext context = DbContext.getInstance(); 031 032 private Ebean() { 033 } 034 035 /** 036 * Get the Database for a given DataSource. If name is null this will 037 * return the 'default' EbeanServer. 038 * <p> 039 * This is provided to access EbeanServer for databases other than the 040 * 'default' database. EbeanServer also provides more control over 041 * transactions and the ability to use transactions created externally to 042 * Ebean. 043 * </p> 044 * <pre>{@code 045 * // use the "hr" database 046 * EbeanServer hrDatabase = Ebean.getServer("hr"); 047 * 048 * Person person = hrDatabase.find(Person.class, 10); 049 * }</pre> 050 * 051 * @param name the name of the server, can use null for the 'default server' 052 */ 053 public static EbeanServer getServer(String name) { 054 return (EbeanServer)context.get(name); 055 } 056 057 /** 058 * Returns the default EbeanServer. 059 * <p> 060 * This is equivalent to <code>Ebean.getServer(null);</code> 061 * </p> 062 */ 063 public static EbeanServer getDefaultServer() { 064 return (EbeanServer)context.getDefault(); 065 } 066 067 /** 068 * Register the server with this Ebean singleton. Specify if the registered 069 * server is the primary/default database. 070 */ 071 @Deprecated 072 public static void register(EbeanServer server, boolean defaultServer) { 073 context.register(server, defaultServer); 074 } 075 076 /** 077 * Backdoor for registering a mock implementation of EbeanServer as the default database. 078 */ 079 protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) { 080 return (EbeanServer)context.mock(name, server, defaultServer); 081 } 082 083 private static Database getDefault() { 084 return context.getDefault(); 085 } 086 087 /** 088 * Return the ExpressionFactory from the default database. 089 * <p> 090 * The ExpressionFactory is used internally by the query and ExpressionList to 091 * build the WHERE and HAVING clauses. Alternatively you can use the 092 * ExpressionFactory directly to create expressions to add to the query where 093 * clause. 094 * </p> 095 * <p> 096 * Alternatively you can use the {@link Expr} as a shortcut to the 097 * ExpressionFactory of the 'Default' EbeanServer. 098 * </p> 099 * <p> 100 * You generally need to the an ExpressionFactory (or {@link Expr}) to build 101 * an expression that uses OR like Expression e = Expr.or(..., ...); 102 * </p> 103 */ 104 public static ExpressionFactory getExpressionFactory() { 105 return getDefault().expressionFactory(); 106 } 107 108 /** 109 * Return the next identity value for a given bean type. 110 * <p> 111 * This will only work when a IdGenerator is on this bean type such as a DB 112 * sequence or UUID. 113 * </p> 114 * <p> 115 * For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do 116 * not need to use this method generally. It is made available for more 117 * complex cases where it is useful to get an ID prior to some processing. 118 * </p> 119 */ 120 public static Object nextId(Class<?> beanType) { 121 return getDefault().nextId(beanType); 122 } 123 124 /** 125 * Start a transaction with 'REQUIRED' semantics. 126 * <p> 127 * With REQUIRED semantics if an active transaction already exists that transaction will be used. 128 * </p> 129 * <p> 130 * The transaction is stored in a ThreadLocal variable and typically you only 131 * need to use the returned Transaction <em>IF</em> you wish to do things like 132 * use batch mode, change the transaction isolation level, use savepoints or 133 * log comments to the transaction log. 134 * </p> 135 * <p> 136 * Example of using a transaction to span multiple calls to find(), save() 137 * etc. 138 * </p> 139 * <pre>{@code 140 * 141 * // start a transaction (stored in a ThreadLocal) 142 * Ebean.beginTransaction(); 143 * try { 144 * Order order = Ebean.find(Order.class,10); ... 145 * 146 * Ebean.save(order); 147 * 148 * Ebean.commitTransaction(); 149 * 150 * } finally { 151 * // rollback if we didn't commit 152 * // i.e. an exception occurred before commitTransaction(). 153 * Ebean.endTransaction(); 154 * } 155 * 156 * }</pre> 157 * <p> 158 * If you want to externalise the transaction management then you should be 159 * able to do this via EbeanServer. Specifically with EbeanServer you can pass 160 * the transaction to the various find() and save() execute() methods. This 161 * gives you the ability to create the transactions yourself externally from 162 * Ebean and pass those transactions through to the various methods available 163 * on EbeanServer. 164 * </p> 165 */ 166 public static Transaction beginTransaction() { 167 return getDefault().beginTransaction(); 168 } 169 170 /** 171 * Start a transaction additionally specifying the isolation level. 172 * 173 * @param isolation the Transaction isolation level 174 */ 175 public static Transaction beginTransaction(TxIsolation isolation) { 176 return getDefault().beginTransaction(isolation); 177 } 178 179 /** 180 * Start a transaction typically specifying REQUIRES_NEW or REQUIRED semantics. 181 * <p> 182 * Note that this provides an try finally alternative to using {@link #executeCall(TxScope, Callable)} or 183 * {@link #execute(TxScope, Runnable)}. 184 * </p> 185 * <p> 186 * <h3>REQUIRES_NEW example:</h3> 187 * <pre>{@code 188 * // Start a new transaction. If there is a current transaction 189 * // suspend it until this transaction ends 190 * Transaction txn = Ebean.beginTransaction(TxScope.requiresNew()); 191 * try { 192 * 193 * ... 194 * 195 * // commit the transaction 196 * txn.commit(); 197 * 198 * } finally { 199 * // end this transaction which: 200 * // A) will rollback transaction if it has not been committed already 201 * // B) will restore a previously suspended transaction 202 * txn.end(); 203 * } 204 * 205 * }</pre> 206 * <h3>REQUIRED example:</h3> 207 * <pre>{@code 208 * 209 * // start a new transaction if there is not a current transaction 210 * Transaction txn = Ebean.beginTransaction(TxScope.required()); 211 * try { 212 * 213 * ... 214 * 215 * // commit the transaction if it was created or 216 * // do nothing if there was already a current transaction 217 * txn.commit(); 218 * 219 * } finally { 220 * // end this transaction which will rollback the transaction 221 * // if it was created for this try finally scope and has not 222 * // already been committed 223 * txn.end(); 224 * } 225 * 226 * }</pre> 227 */ 228 public static Transaction beginTransaction(TxScope scope) { 229 return getDefault().beginTransaction(scope); 230 } 231 232 /** 233 * Returns the current transaction or null if there is no current transaction 234 * in scope. 235 */ 236 public static Transaction currentTransaction() { 237 return getDefault().currentTransaction(); 238 } 239 240 /** 241 * The batch will be flushing automatically but you can use this to explicitly 242 * flush the batch if you like. 243 * <p> 244 * Flushing occurs automatically when: 245 * </p> 246 * <ul> 247 * <li>the batch size is reached</li> 248 * <li>A query is executed on the same transaction</li> 249 * <li>UpdateSql or CallableSql are mixed with bean save and delete</li> 250 * <li>Transaction commit occurs</li> 251 * <li>A getter method is called on a batched bean</li> 252 * </ul> 253 */ 254 public static void flush() { 255 currentTransaction().flush(); 256 } 257 258 /** 259 * Register a TransactionCallback on the currently active transaction. 260 * <p/> 261 * If there is no currently active transaction then a PersistenceException is thrown. 262 * 263 * @param transactionCallback the transaction callback to be registered with the current transaction 264 * @throws PersistenceException if there is no currently active transaction 265 */ 266 public static void register(TransactionCallback transactionCallback) throws PersistenceException { 267 getDefault().register(transactionCallback); 268 } 269 270 /** 271 * Commit the current transaction. 272 */ 273 public static void commitTransaction() { 274 getDefault().commitTransaction(); 275 } 276 277 /** 278 * Rollback the current transaction. 279 */ 280 public static void rollbackTransaction() { 281 getDefault().rollbackTransaction(); 282 } 283 284 /** 285 * If the current transaction has already been committed do nothing otherwise 286 * rollback the transaction. 287 * <p> 288 * Useful to put in a finally block to ensure the transaction is ended, rather 289 * than a rollbackTransaction() in each catch block. 290 * </p> 291 * <p> 292 * Code example: 293 * </p> 294 * <pre>{@code 295 * Ebean.beginTransaction(); 296 * try { 297 * // do some fetching and or persisting 298 * 299 * // commit at the end 300 * Ebean.commitTransaction(); 301 * 302 * } finally { 303 * // if commit didn't occur then rollback the transaction 304 * Ebean.endTransaction(); 305 * } 306 * }</pre> 307 */ 308 public static void endTransaction() { 309 getDefault().endTransaction(); 310 } 311 312 /** 313 * Mark the current transaction as rollback only. 314 */ 315 public static void setRollbackOnly() { 316 getDefault().currentTransaction().setRollbackOnly(); 317 } 318 319 /** 320 * Return a map of the differences between two objects of the same type. 321 * <p> 322 * When null is passed in for b, then the 'OldValues' of a is used for the 323 * difference comparison. 324 * </p> 325 */ 326 public static Map<String, ValuePair> diff(Object a, Object b) { 327 return getDefault().diff(a, b); 328 } 329 330 /** 331 * Either Insert or Update the bean depending on its state. 332 * <p> 333 * If there is no current transaction one will be created and committed for 334 * you automatically. 335 * </p> 336 * <p> 337 * Save can cascade along relationships. For this to happen you need to 338 * specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the 339 * OneToMany, OneToOne or ManyToMany annotation. 340 * </p> 341 * <p> 342 * In this example below the details property has a CascadeType.ALL set so 343 * saving an order will also save all its details. 344 * </p> 345 * <pre>{@code 346 * public class Order { ... 347 * 348 * @OneToMany(cascade=CascadeType.ALL, mappedBy="order") 349 * List<OrderDetail> details; 350 * ... 351 * } 352 * }</pre> 353 * <p> 354 * When a save cascades via a OneToMany or ManyToMany Ebean will automatically 355 * set the 'parent' object to the 'detail' object. In the example below in 356 * saving the order and cascade saving the order details the 'parent' order 357 * will be set against each order detail when it is saved. 358 * </p> 359 */ 360 public static void save(Object bean) throws OptimisticLockException { 361 getDefault().save(bean); 362 } 363 364 /** 365 * Insert the bean. This is useful when you set the Id property on a bean and 366 * want to explicitly insert it. 367 */ 368 public static void insert(Object bean) { 369 getDefault().insert(bean); 370 } 371 372 /** 373 * Insert a collection of beans. 374 */ 375 public static void insertAll(Collection<?> beans) { 376 getDefault().insertAll(beans); 377 } 378 379 /** 380 * Marks the entity bean as dirty. 381 * <p> 382 * This is used so that when a bean that is otherwise unmodified is updated with the version 383 * property updated. 384 * <p> 385 * An unmodified bean that is saved or updated is normally skipped and this marks the bean as 386 * dirty so that it is not skipped. 387 * <pre>{@code 388 * 389 * Customer customer = Ebean.find(Customer, id); 390 * 391 * // mark the bean as dirty so that a save() or update() will 392 * // increment the version property 393 * Ebean.markAsDirty(customer); 394 * Ebean.save(customer); 395 * 396 * }</pre> 397 */ 398 public static void markAsDirty(Object bean) throws OptimisticLockException { 399 getDefault().markAsDirty(bean); 400 } 401 402 /** 403 * Saves the bean using an update. If you know you are updating a bean then it is preferrable to 404 * use this update() method rather than save(). 405 * <p> 406 * <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call 407 * update().You can create a new instance and set some of its properties programmatically for via 408 * JSON/XML marshalling etc. This is described as a 'stateless update'. 409 * </p> 410 * <p> 411 * <b>Optimistic Locking: </b> Note that if the version property is not set when update() is 412 * called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used). 413 * </p> 414 * <pre>{@code 415 * 416 * // A 'stateless update' example 417 * Customer customer = new Customer(); 418 * customer.setId(7); 419 * customer.setName("ModifiedNameNoOCC"); 420 * 421 * DB.update(customer); 422 * 423 * }</pre> 424 */ 425 public static void update(Object bean) throws OptimisticLockException { 426 getDefault().update(bean); 427 } 428 429 /** 430 * Update the beans in the collection. 431 */ 432 public static void updateAll(Collection<?> beans) throws OptimisticLockException { 433 getDefault().updateAll(beans); 434 } 435 436 /** 437 * Merge the bean using the default merge options. 438 * 439 * @param bean The bean to merge 440 */ 441 public static void merge(Object bean) { 442 getDefault().merge(bean); 443 } 444 445 /** 446 * Merge the bean using the given merge options. 447 * 448 * @param bean The bean to merge 449 * @param options The options to control the merge 450 */ 451 public static void merge(Object bean, MergeOptions options) { 452 getDefault().merge(bean, options); 453 } 454 455 /** 456 * Save all the beans from a Collection. 457 */ 458 public static int saveAll(Collection<?> beans) throws OptimisticLockException { 459 return getDefault().saveAll(beans); 460 } 461 462 /** 463 * This method checks the uniqueness of a bean. I.e. if the save will work. It will return the 464 * properties that violates an unique / primary key. This may be done in an UI save action to 465 * validate if the user has entered correct values. 466 * <p> 467 * Note: This method queries the DB for uniqueness of all indices, so do not use it in a batch update. 468 * <p> 469 * Note: This checks only the root bean! 470 * <p> 471 * <pre>{@code 472 * 473 * // there is a unique constraint on title 474 * 475 * Document doc = new Document(); 476 * doc.setTitle("One flew over the cuckoo's nest"); 477 * doc.setBody("clashes with doc1"); 478 * 479 * Set<Property> properties = server().checkUniqueness(doc); 480 * 481 * if (properties.isEmpty()) { 482 * // it is unique ... carry on 483 * 484 * } else { 485 * // build a user friendly message 486 * // to return message back to user 487 * 488 * String uniqueProperties = properties.toString(); 489 * 490 * StringBuilder msg = new StringBuilder(); 491 * 492 * properties.forEach((it)-> { 493 * Object propertyValue = it.getVal(doc); 494 * String propertyName = it.getName(); 495 * msg.append(" property["+propertyName+"] value["+propertyValue+"]"); 496 * }); 497 * 498 * // uniqueProperties > [title] 499 * // custom msg > property[title] value[One flew over the cuckoo's nest] 500 * 501 * } 502 * 503 * }</pre> 504 * 505 * @param bean The entity bean to check uniqueness on 506 * @return a set of Properties if constraint validation was detected or empty list. 507 */ 508 public static Set<Property> checkUniqueness(Object bean) { 509 return getDefault().checkUniqueness(bean); 510 } 511 512 /** 513 * Same as {@link #checkUniqueness(Object)}. but with given transaction. 514 */ 515 public static Set<Property> checkUniqueness(Object bean, Transaction transaction) { 516 return getDefault().checkUniqueness(bean, transaction); 517 } 518 519 /** 520 * Delete the bean. 521 * <p> 522 * This will return true if the bean was deleted successfully or JDBC batch is being used. 523 * </p> 524 * <p> 525 * If there is no current transaction one will be created and committed for 526 * you automatically. 527 * </p> 528 * <p> 529 * If the bean is configured with <code>@SoftDelete</code> then this will perform a soft 530 * delete rather than a hard/permanent delete. 531 * </p> 532 * <p> 533 * If the Bean does not have a version property (or loaded version property) and 534 * the bean does not exist then this returns false indicating that nothing was 535 * deleted. Note that, if JDBC batch mode is used then this always returns true. 536 * </p> 537 */ 538 public static boolean delete(Object bean) throws OptimisticLockException { 539 return getDefault().delete(bean); 540 } 541 542 /** 543 * Delete the bean in permanent fashion (will not use soft delete). 544 */ 545 public static boolean deletePermanent(Object bean) throws OptimisticLockException { 546 return getDefault().deletePermanent(bean); 547 } 548 549 /** 550 * Delete the bean given its type and id. 551 */ 552 public static int delete(Class<?> beanType, Object id) { 553 return getDefault().delete(beanType, id); 554 } 555 556 /** 557 * Delete permanent the bean given its type and id. 558 */ 559 public static int deletePermanent(Class<?> beanType, Object id) { 560 return getDefault().deletePermanent(beanType, id); 561 } 562 563 /** 564 * Delete several beans given their type and id values. 565 */ 566 public static int deleteAll(Class<?> beanType, Collection<?> ids) { 567 return getDefault().deleteAll(beanType, ids); 568 } 569 570 /** 571 * Delete permanent several beans given their type and id values. 572 */ 573 public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) { 574 return getDefault().deleteAllPermanent(beanType, ids); 575 } 576 577 /** 578 * Delete all the beans in the Collection. 579 */ 580 public static int deleteAll(Collection<?> beans) throws OptimisticLockException { 581 return getDefault().deleteAll(beans); 582 } 583 584 /** 585 * Delete permanent all the beans in the Collection (will not use soft delete). 586 */ 587 public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException { 588 return getDefault().deleteAllPermanent(beans); 589 } 590 591 /** 592 * Refresh the values of a bean. 593 * <p> 594 * Note that this resets OneToMany and ManyToMany properties so that if they 595 * are accessed a lazy load will refresh the many property. 596 * </p> 597 */ 598 public static void refresh(Object bean) { 599 getDefault().refresh(bean); 600 } 601 602 /** 603 * Refresh a 'many' property of a bean. 604 * <pre>{@code 605 * 606 * Order order = ...; 607 * ... 608 * // refresh the order details... 609 * Ebean.refreshMany(order, "details"); 610 * 611 * }</pre> 612 * 613 * @param bean the entity bean containing the List Set or Map to refresh. 614 * @param manyPropertyName the property name of the List Set or Map to refresh. 615 */ 616 public static void refreshMany(Object bean, String manyPropertyName) { 617 getDefault().refreshMany(bean, manyPropertyName); 618 } 619 620 /** 621 * Get a reference object. 622 * <p> 623 * This is sometimes described as a proxy (with lazy loading). 624 * </p> 625 * <pre>{@code 626 * 627 * Product product = Ebean.getReference(Product.class, 1); 628 * 629 * // You can get the id without causing a fetch/lazy load 630 * Integer productId = product.getId(); 631 * 632 * // If you try to get any other property a fetch/lazy loading will occur 633 * // This will cause a query to execute... 634 * String name = product.getName(); 635 * 636 * }</pre> 637 * 638 * @param beanType the type of entity bean 639 * @param id the id value 640 */ 641 public static <T> T getReference(Class<T> beanType, Object id) { 642 return getDefault().reference(beanType, id); 643 } 644 645 /** 646 * Sort the list using the sortByClause which can contain a comma delimited 647 * list of property names and keywords asc, desc, nullsHigh and nullsLow. 648 * <ul> 649 * <li>asc - ascending order (which is the default)</li> 650 * <li>desc - Descending order</li> 651 * <li>nullsHigh - Treat null values as high/large values (which is the 652 * default)</li> 653 * <li>nullsLow- Treat null values as low/very small values</li> 654 * </ul> 655 * <p> 656 * If you leave off any keywords the defaults are ascending order and treating 657 * nulls as high values. 658 * </p> 659 * <p> 660 * Note that the sorting uses a Comparator and Collections.sort(); and does 661 * not invoke a DB query. 662 * </p> 663 * <pre>{@code 664 * 665 * // find orders and their customers 666 * List<Order> list = Ebean.find(Order.class) 667 * .fetch("customer") 668 * .order("id") 669 * .findList(); 670 * 671 * // sort by customer name ascending, then by order shipDate 672 * // ... then by the order status descending 673 * Ebean.sort(list, "customer.name, shipDate, status desc"); 674 * 675 * // sort by customer name descending (with nulls low) 676 * // ... then by the order id 677 * Ebean.sort(list, "customer.name desc nullsLow, id"); 678 * 679 * }</pre> 680 * 681 * @param list the list of entity beans 682 * @param sortByClause the properties to sort the list by 683 */ 684 public static <T> void sort(List<T> list, String sortByClause) { 685 getDefault().sort(list, sortByClause); 686 } 687 688 /** 689 * Find a bean using its unique id. This will not use caching. 690 * <pre>{@code 691 * 692 * // Fetch order 1 693 * Order order = Ebean.find(Order.class, 1); 694 * 695 * }</pre> 696 * <p> 697 * If you want more control over the query then you can use createQuery() and 698 * Query.findOne(); 699 * </p> 700 * <pre>{@code 701 * 702 * // ... additionally fetching customer, customer shipping address, 703 * // order details, and the product associated with each order detail. 704 * // note: only product id and name is fetch (its a "partial object"). 705 * // note: all other objects use "*" and have all their properties fetched. 706 * 707 * Query<Order> query = Ebean.find(Order.class) 708 * .setId(1) 709 * .fetch("customer") 710 * .fetch("customer.shippingAddress") 711 * .fetch("details") 712 * .query(); 713 * 714 * // fetch associated products but only fetch their product id and name 715 * query.fetch("details.product", "name"); 716 * 717 * // traverse the object graph... 718 * 719 * Order order = query.findOne(); 720 * 721 * Customer customer = order.getCustomer(); 722 * Address shippingAddress = customer.getShippingAddress(); 723 * List<OrderDetail> details = order.getDetails(); 724 * OrderDetail detail0 = details.get(0); 725 * Product product = detail0.getProduct(); 726 * String productName = product.getName(); 727 * 728 * }</pre> 729 * 730 * @param beanType the type of entity bean to fetch 731 * @param id the id value 732 */ 733 @Nullable 734 public static <T> T find(Class<T> beanType, Object id) { 735 return getDefault().find(beanType, id); 736 } 737 738 /** 739 * Deprecated - migrate to DB.sqlQuery(). 740 * <p> 741 * Create a SqlQuery for executing native sql 742 * query statements. 743 * <p> 744 * Note that you can use raw SQL with entity beans, refer to the SqlSelect 745 * annotation for examples. 746 * </p> 747 */ 748 @Deprecated 749 public static SqlQuery createSqlQuery(String sql) { 750 return getDefault().sqlQuery(sql); 751 } 752 753 /** 754 * Deprecated - migrate to DB.sqlUpdate(). 755 * <p> 756 * Create a sql update for executing native dml statements. 757 * <p> 758 * Use this to execute a Insert Update or Delete statement. The statement will 759 * be native to the database and contain database table and column names. 760 * <p> 761 * See {@link SqlUpdate} for example usage. 762 */ 763 @Deprecated 764 public static SqlUpdate createSqlUpdate(String sql) { 765 return getDefault().sqlUpdate(sql); 766 } 767 768 /** 769 * Create a CallableSql to execute a given stored procedure. 770 * 771 * @see CallableSql 772 */ 773 public static CallableSql createCallableSql(String sql) { 774 return getDefault().createCallableSql(sql); 775 } 776 777 /** 778 * Create a orm update where you will supply the insert/update or delete 779 * statement (rather than using a named one that is already defined using the 780 * @NamedUpdates annotation). 781 * <p> 782 * The orm update differs from the sql update in that it you can use the bean 783 * name and bean property names rather than table and column names. 784 * </p> 785 * <p> 786 * An example: 787 * </p> 788 * <pre>{@code 789 * 790 * // The bean name and properties - "topic","postCount" and "id" 791 * 792 * // will be converted into their associated table and column names 793 * String updStatement = "update topic set postCount = :pc where id = :id"; 794 * 795 * Update<Topic> update = Ebean.createUpdate(Topic.class, updStatement); 796 * 797 * update.set("pc", 9); 798 * update.set("id", 3); 799 * 800 * int rows = update.execute(); 801 * System.out.println("rows updated:" + rows); 802 * 803 * }</pre> 804 */ 805 public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) { 806 return getDefault().createUpdate(beanType, ormUpdate); 807 } 808 809 /** 810 * Create a CsvReader for a given beanType. 811 */ 812 public static <T> CsvReader<T> createCsvReader(Class<T> beanType) { 813 return getDefault().createCsvReader(beanType); 814 } 815 816 /** 817 * Create a named query. 818 * <p> 819 * For RawSql the named query is expected to be in ebean.xml. 820 * </p> 821 * 822 * @param beanType The type of entity bean 823 * @param namedQuery The name of the query 824 * @param <T> The type of entity bean 825 * @return The query 826 */ 827 public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) { 828 return getDefault().createNamedQuery(beanType, namedQuery); 829 } 830 831 /** 832 * Create a query for a type of entity bean. 833 * <p> 834 * You can use the methods on the Query object to specify fetch paths, 835 * predicates, order by, limits etc. 836 * </p> 837 * <p> 838 * You then use findList(), findSet(), findMap() and findOne() to execute 839 * the query and return the collection or bean. 840 * </p> 841 * <p> 842 * Note that a query executed by {@link Query#findList()} 843 * {@link Query#findSet()} etc will execute against the same EbeanServer from 844 * which is was created. 845 * </p> 846 * 847 * @param beanType the class of entity to be fetched 848 * @return A ORM Query object for this beanType 849 */ 850 public static <T> Query<T> createQuery(Class<T> beanType) { 851 return getDefault().createQuery(beanType); 852 } 853 854 /** 855 * Parse the Ebean query language statement returning the query which can then 856 * be modified (add expressions, change order by clause, change maxRows, change 857 * fetch and select paths etc). 858 * <p> 859 * <h3>Example</h3> 860 * <pre>{@code 861 * 862 * // Find order additionally fetching the customer, details and details.product name. 863 * 864 * String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId "; 865 * 866 * Query<Order> query = Ebean.createQuery(Order.class, eql); 867 * query.setParameter("orderId", 2); 868 * 869 * Order order = query.findOne(); 870 * 871 * // This is the same as: 872 * 873 * Order order = Ebean.find(Order.class) 874 * .fetch("customer") 875 * .fetch("details") 876 * .fetch("detail.product", "name") 877 * .setId(2) 878 * .findOne(); 879 * 880 * }</pre> 881 * 882 * @param beanType The type of bean to fetch 883 * @param eql The Ebean query 884 * @param <T> The type of the entity bean 885 * @return The query with expressions defined as per the parsed query statement 886 */ 887 public static <T> Query<T> createQuery(Class<T> beanType, String eql) { 888 return getDefault().createQuery(beanType, eql); 889 } 890 891 /** 892 * Create a query for a type of entity bean. 893 * <p> 894 * This is actually the same as {@link #createQuery(Class)}. The reason it 895 * exists is that people used to JPA will probably be looking for a 896 * createQuery method (the same as entityManager). 897 * </p> 898 * 899 * @param beanType the type of entity bean to find 900 * @return A ORM Query object for this beanType 901 */ 902 public static <T> Query<T> find(Class<T> beanType) { 903 return getDefault().find(beanType); 904 } 905 906 /** 907 * Create a query using native SQL. 908 * <p> 909 * The native SQL can contain named parameters or positioned parameters. 910 * </p> 911 * <pre>{@code 912 * 913 * String sql = "select c.id, c.name from customer c where c.name like ? order by c.name"; 914 * 915 * List<Customer> customers = DB.findNative(Customer.class, sql) 916 * .setParameter(1, "Rob%") 917 * .findList() 918 * 919 * }</pre> 920 * 921 * @param beanType The type of entity bean to fetch 922 * @param nativeSql The SQL that can contain named or positioned parameters 923 * @return The query to set parameters and execute 924 */ 925 public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) { 926 return getDefault().findNative(beanType, nativeSql); 927 } 928 929 /** 930 * Create a Query for DTO beans. 931 * <p> 932 * DTO beans are just normal bean like classes with public constructor(s) and setters. 933 * They do not need to be registered with Ebean before use. 934 * </p> 935 * 936 * @param dtoType The type of the DTO bean the rows will be mapped into. 937 * @param sql The SQL query to execute. 938 * @param <T> The type of the DTO bean. 939 */ 940 public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) { 941 return getDefault().findDto(dtoType, sql); 942 } 943 944 /** 945 * Create an Update query to perform a bulk update. 946 * <p> 947 * <pre>{@code 948 * 949 * int rows = Ebean.update(Customer.class) 950 * .set("status", Customer.Status.ACTIVE) 951 * .set("updtime", new Timestamp(System.currentTimeMillis())) 952 * .where() 953 * .gt("id", 1000) 954 * .update(); 955 * 956 * }</pre> 957 * 958 * @param beanType The type of entity bean to update 959 * @param <T> The type of entity bean 960 * @return The update query to use 961 */ 962 public static <T> UpdateQuery<T> update(Class<T> beanType) { 963 return getDefault().update(beanType); 964 } 965 966 /** 967 * Create a filter for sorting and filtering lists of entities locally without 968 * going back to the database. 969 * <p> 970 * This produces and returns a new list with the sort and filters applied. 971 * </p> 972 * <p> 973 * Refer to {@link Filter} for an example of its use. 974 * </p> 975 */ 976 public static <T> Filter<T> filter(Class<T> beanType) { 977 return getDefault().filter(beanType); 978 } 979 980 /** 981 * Execute a Sql Update Delete or Insert statement. This returns the number of 982 * rows that where updated, deleted or inserted. If is executed in batch then 983 * this returns -1. You can get the actual rowCount after commit() from 984 * updateSql.getRowCount(). 985 * <p> 986 * If you wish to execute a Sql Select natively then you should use the 987 * FindByNativeSql object. 988 * </p> 989 * <p> 990 * Note that the table modification information is automatically deduced and 991 * you do not need to call the Ebean.externalModification() method when you 992 * use this method. 993 * </p> 994 * <p> 995 * Example: 996 * </p> 997 * <pre>{@code 998 * 999 * // example that uses 'named' parameters 1000 * String s = "UPDATE f_topic set post_count = :count where id = :id" 1001 * 1002 * SqlUpdate update = Ebean.createSqlUpdate(s); 1003 * 1004 * update.setParameter("id", 1); 1005 * update.setParameter("count", 50); 1006 * 1007 * int modifiedCount = Ebean.execute(update); 1008 * 1009 * String msg = "There where " + modifiedCount + "rows updated"; 1010 * 1011 * }</pre> 1012 * 1013 * @param sqlUpdate the update sql potentially with bind values 1014 * @return the number of rows updated or deleted. -1 if executed in batch. 1015 * @see SqlUpdate 1016 * @see CallableSql 1017 * @see Ebean#execute(CallableSql) 1018 */ 1019 public static int execute(SqlUpdate sqlUpdate) { 1020 return getDefault().execute(sqlUpdate); 1021 } 1022 1023 /** 1024 * For making calls to stored procedures. 1025 * <p> 1026 * Example: 1027 * </p> 1028 * <pre>{@code 1029 * 1030 * String sql = "{call sp_order_modify(?,?,?)}"; 1031 * 1032 * CallableSql cs = Ebean.createCallableSql(sql); 1033 * cs.setParameter(1, 27); 1034 * cs.setParameter(2, "SHIPPED"); 1035 * cs.registerOut(3, Types.INTEGER); 1036 * 1037 * Ebean.execute(cs); 1038 * 1039 * // read the out parameter 1040 * Integer returnValue = (Integer) cs.getObject(3); 1041 * 1042 * }</pre> 1043 * 1044 * @see CallableSql 1045 * @see Ebean#execute(SqlUpdate) 1046 */ 1047 public static int execute(CallableSql callableSql) { 1048 return getDefault().execute(callableSql); 1049 } 1050 1051 /** 1052 * Execute a TxRunnable in a Transaction with an explicit scope. 1053 * <p> 1054 * The scope can control the transaction type, isolation and rollback 1055 * semantics. 1056 * </p> 1057 * <pre>{@code 1058 * 1059 * // set specific transactional scope settings 1060 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1061 * 1062 * Ebean.execute(scope, new TxRunnable() { 1063 * public void run() { 1064 * User u1 = Ebean.find(User.class, 1); 1065 * ... 1066 * } 1067 * }); 1068 * 1069 * }</pre> 1070 */ 1071 public static void execute(TxScope scope, Runnable r) { 1072 getDefault().execute(scope, r); 1073 } 1074 1075 /** 1076 * Execute a Runnable in a Transaction with the default scope. 1077 * <p> 1078 * The default scope runs with REQUIRED and by default will rollback on any 1079 * exception (checked or runtime). 1080 * </p> 1081 * <pre>{@code 1082 * 1083 * Ebean.execute(() -> { 1084 * 1085 * User u1 = Ebean.find(User.class, 1); 1086 * User u2 = Ebean.find(User.class, 2); 1087 * 1088 * u1.setName("u1 mod"); 1089 * u2.setName("u2 mod"); 1090 * 1091 * Ebean.save(u1); 1092 * Ebean.save(u2); 1093 * 1094 * }); 1095 * 1096 * }</pre> 1097 */ 1098 public static void execute(Runnable r) { 1099 getDefault().execute(r); 1100 } 1101 1102 /** 1103 * Execute a Callable in a Transaction with an explicit scope. 1104 * <p> 1105 * The scope can control the transaction type, isolation and rollback 1106 * semantics. 1107 * </p> 1108 * <pre>{@code 1109 * 1110 * // set specific transactional scope settings 1111 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1112 * 1113 * Ebean.executeCall(scope, new Callable<String>() { 1114 * public String call() { 1115 * User u1 = Ebean.find(User.class, 1); 1116 * ... 1117 * return u1.getEmail(); 1118 * } 1119 * }); 1120 * 1121 * }</pre> 1122 */ 1123 public static <T> T executeCall(TxScope scope, Callable<T> c) { 1124 return getDefault().executeCall(scope, c); 1125 } 1126 1127 /** 1128 * Execute a Callable in a Transaction with the default scope. 1129 * <p> 1130 * The default scope runs with REQUIRED and by default will rollback on any 1131 * exception (checked or runtime). 1132 * </p> 1133 * <p> 1134 * This is basically the same as TxRunnable except that it returns an Object 1135 * (and you specify the return type via generics). 1136 * </p> 1137 * <pre>{@code 1138 * 1139 * Ebean.executeCall(() -> { 1140 * 1141 * User u1 = Ebean.find(User.class, 1); 1142 * User u2 = Ebean.find(User.class, 2); 1143 * 1144 * u1.setName("u1 mod"); 1145 * u2.setName("u2 mod"); 1146 * 1147 * Ebean.save(u1); 1148 * Ebean.save(u2); 1149 * 1150 * return u1.getEmail(); 1151 * 1152 * }); 1153 * 1154 * }</pre> 1155 */ 1156 public static <T> T executeCall(Callable<T> c) { 1157 return getDefault().executeCall(c); 1158 } 1159 1160 /** 1161 * Inform Ebean that tables have been modified externally. These could be the 1162 * result of from calling a stored procedure, other JDBC calls or external 1163 * programs including other frameworks. 1164 * <p> 1165 * If you use Ebean.execute(UpdateSql) then the table modification information 1166 * is automatically deduced and you do not need to call this method yourself. 1167 * </p> 1168 * <p> 1169 * This information is used to invalidate objects out of the cache and 1170 * potentially text indexes. This information is also automatically broadcast 1171 * across the cluster. 1172 * </p> 1173 * <p> 1174 * If there is a transaction then this information is placed into the current 1175 * transactions event information. When the transaction is committed this 1176 * information is registered (with the transaction manager). If this 1177 * transaction is rolled back then none of the transaction event information 1178 * registers including the information you put in via this method. 1179 * </p> 1180 * <p> 1181 * If there is NO current transaction when you call this method then this 1182 * information is registered immediately (with the transaction manager). 1183 * </p> 1184 * 1185 * @param tableName the name of the table that was modified 1186 * @param inserts true if rows where inserted into the table 1187 * @param updates true if rows on the table where updated 1188 * @param deletes true if rows on the table where deleted 1189 */ 1190 public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) { 1191 getDefault().externalModification(tableName, inserts, updates, deletes); 1192 } 1193 1194 /** 1195 * Return the BeanState for a given entity bean. 1196 * <p> 1197 * This will return null if the bean is not an enhanced entity bean. 1198 * </p> 1199 */ 1200 public static BeanState getBeanState(Object bean) { 1201 return getDefault().beanState(bean); 1202 } 1203 1204 /** 1205 * Return the manager of the server cache ("L2" cache). 1206 */ 1207 public static ServerCacheManager getServerCacheManager() { 1208 return getDefault().cacheManager(); 1209 } 1210 1211 /** 1212 * Return the BackgroundExecutor service for asynchronous processing of 1213 * queries. 1214 */ 1215 public static BackgroundExecutor getBackgroundExecutor() { 1216 return getDefault().backgroundExecutor(); 1217 } 1218 1219 /** 1220 * Return the JsonContext for reading/writing JSON. 1221 */ 1222 public static JsonContext json() { 1223 return getDefault().json(); 1224 } 1225 1226}