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