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