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