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