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