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