#1424 - Deprecate / Move ... finder methods that take explicit transaction to ExtendedServer API

This commit is contained in:
rob bygrave
2018-06-14 11:03:29 +12:00
parent a61db2ab35
commit e21839de91
8 changed files with 562 additions and 12 deletions
+58
View File
@@ -808,22 +808,41 @@ public interface EbeanServer {
<T> T getReference(Class<T> beanType, Object id);
/**
* Return the extended API for EbeanServer.
* <p>
* The extended API has the options for executing queries that take an explicit
* transaction as an argument.
* </p>
* <p>
* Typically we only need to use the extended API when we do NOT want to use the
* usual ThreadLocal based mechanism to obtain the current transaction but instead
* supply the transaction explicitly.
* </p>
*/
ExtendedServer extended();
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Return the number of 'top level' or 'root' entities this query should return.
*
* @see Query#findCount()
* @see Query#findFutureCount()
*/
@Deprecated
<T> int findCount(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Return the Id values of the query as a List.
*
* @see Query#findIds()
*/
@Nonnull
@Deprecated
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Return a QueryIterator for the query.
* <p>
* Generally using {@link #findEach(Query, Consumer, Transaction)} or
@@ -841,9 +860,11 @@ public interface EbeanServer {
* @see Query#findEachWhile(Predicate)
*/
@Nonnull
@Deprecated
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query visiting the each bean one at a time.
* <p>
* Unlike findList() this is suitable for processing a query that will return
@@ -871,9 +892,11 @@ public interface EbeanServer {
* @see Query#findEach(Consumer)
* @see Query#findEachWhile(Predicate)
*/
@Deprecated
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query visiting the each bean one at a time.
* <p>
* Compared to findEach() this provides the ability to stop processing the query
@@ -908,9 +931,11 @@ public interface EbeanServer {
* @see Query#findEach(Consumer)
* @see Query#findEachWhile(Predicate)
*/
@Deprecated
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Return versions of a @History entity bean.
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
@@ -918,9 +943,11 @@ public interface EbeanServer {
* </p>
*/
@Nonnull
@Deprecated
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute a query returning a list of beans.
* <p>
* Generally you are able to use {@link Query#findList()} rather than
@@ -944,9 +971,11 @@ public interface EbeanServer {
* @see Query#findList()
*/
@Nonnull
@Deprecated
<T> List<T> findList(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute find row count query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
@@ -960,9 +989,11 @@ public interface EbeanServer {
* @see Query#findFutureCount()
*/
@Nonnull
@Deprecated
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute find Id's query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
@@ -976,9 +1007,11 @@ public interface EbeanServer {
* @see Query#findFutureIds()
*/
@Nonnull
@Deprecated
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute find list query in a background thread returning a FutureList object.
* <p>
* This returns a Future object which can be used to cancel, check the
@@ -993,9 +1026,11 @@ public interface EbeanServer {
* @see Query#findFutureList()
*/
@Nonnull
@Deprecated
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Return a PagedList for this query using firstRow and maxRows.
* <p>
* The benefit of using this over findList() is that it provides functionality to get the
@@ -1025,9 +1060,11 @@ public interface EbeanServer {
* @see Query#findPagedList()
*/
@Nonnull
@Deprecated
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query returning a set of entity beans.
* <p>
* Generally you are able to use {@link Query#findSet()} rather than
@@ -1051,9 +1088,11 @@ public interface EbeanServer {
* @see Query#findSet()
*/
@Nonnull
@Deprecated
<T> Set<T> findSet(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query returning the entity beans in a Map.
* <p>
* Generally you are able to use {@link Query#findMap()} rather than
@@ -1068,9 +1107,11 @@ public interface EbeanServer {
* @see Query#findMap()
*/
@Nonnull
@Deprecated
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query returning a list of values for a single property.
* <p>
* <h3>Example 1:</h3>
@@ -1101,9 +1142,11 @@ public interface EbeanServer {
* @see Query#findSingleAttributeList()
*/
@Nonnull
@Deprecated
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the query returning at most one entity bean or null (if no matching
* bean is found).
* <p>
@@ -1123,15 +1166,19 @@ public interface EbeanServer {
* @see Query#findOne()
*/
@Nullable
@Deprecated
<T> T findOne(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Similar to findOne() but returns an Optional (rather than nullable).
*/
@Nonnull
@Deprecated
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute as a delete query deleting the 'root level' beans that match the predicates
* in the query.
* <p>
@@ -1144,9 +1191,11 @@ public interface EbeanServer {
* @param <T> the type of entity bean to fetch.
* @return the number of beans/rows that were deleted
*/
@Deprecated
<T> int delete(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the update query returning the number of rows updated.
* <p>
* The update query must be created using {@link #update(Class)}.
@@ -1157,9 +1206,11 @@ public interface EbeanServer {
* @param <T> the type of entity bean
* @return The number of rows updated
*/
@Deprecated
<T> int update(Query<T> query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the sql query returning a list of MapBean.
* <p>
* Generally you are able to use {@link SqlQuery#findList()} rather than
@@ -1173,17 +1224,21 @@ public interface EbeanServer {
* @see SqlQuery#findList()
*/
@Nonnull
@Deprecated
List<SqlRow> findList(SqlQuery query, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the SqlQuery iterating a row at a time.
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
@Deprecated
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the SqlQuery iterating a row at a time with the ability to stop consuming part way through.
* <p>
* Returning false after processing a row stops the iteration through the query results.
@@ -1192,9 +1247,11 @@ public interface EbeanServer {
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
@Deprecated
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
/**
* Deprecated - Moved to the ExtendedServer API, please use via extended().
* Execute the sql query returning a single MapBean or null.
* <p>
* This will throw a PersistenceException if the query found more than one
@@ -1212,6 +1269,7 @@ public interface EbeanServer {
* @see SqlQuery#findOne()
*/
@Nullable
@Deprecated
SqlRow findOne(SqlQuery query, Transaction transaction);
/**
+438
View File
@@ -0,0 +1,438 @@
package io.ebean;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.NonUniqueResultException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* The extended API for EbeanServer.
* <p>
* This provides the finder methods that take an explicit transaction rather than obtaining
* the transaction from the usual mechanism (which is ThreadLocal based).
* </p>
* <p>
* In general we only want to use this ExtendedServer API when we want to avoid / bypass
* the use of the mechanism to get the current transaction and instead explicitly supply
* the transaction to use.
* </p>
* <p>
* Note that in all cases the transaction supplied can be null and in this case the EbeanServer
* will use the normal mechanism to obtain the transaction to use.
* </p>
*/
public interface ExtendedServer {
/**
* Return the number of 'top level' or 'root' entities this query should return.
*
* @see Query#findCount()
* @see Query#findFutureCount()
*/
<T> int findCount(Query<T> query, Transaction transaction);
/**
* Return the Id values of the query as a List.
*
* @see Query#findIds()
*/
@Nonnull
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
/**
* Return a QueryIterator for the query.
* <p>
* Generally using {@link #findEach(Query, Consumer, Transaction)} or
* {@link #findEachWhile(Query, Predicate, Transaction)} is preferred
* to findIterate(). The reason is that those methods automatically take care of
* closing the queryIterator (and the underlying jdbc statement and resultSet).
* </p>
* <p>
* This is similar to findEach in that not all the result beans need to be held
* in memory at the same time and as such is good for processing large queries.
* </p>
*
* @see Query#findIterate()
* @see Query#findEach(Consumer)
* @see Query#findEachWhile(Predicate)
*/
@Nonnull
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Execute the query visiting the each bean one at a time.
* <p>
* Unlike findList() this is suitable for processing a query that will return
* a very large resultSet. The reason is that not all the result beans need to be
* held in memory at the same time and instead processed one at a time.
* </p>
* <p>
* Internally this query using a PersistenceContext scoped to each bean (and the
* beans associated object graph).
* </p>
* <p>
* <pre>{@code
*
* ebeanServer.find(Order.class)
* .where().eq("status", Order.Status.NEW)
* .order().asc("id")
* .findEach((Order order) -> {
*
* // do something with the order bean
* System.out.println(" -- processing order ... " + order);
* });
*
* }</pre>
*
* @see Query#findEach(Consumer)
* @see Query#findEachWhile(Predicate)
*/
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
/**
* Execute the query visiting the each bean one at a time.
* <p>
* Compared to findEach() this provides the ability to stop processing the query
* results early by returning false for the Predicate.
* </p>
* <p>
* Unlike findList() this is suitable for processing a query that will return
* a very large resultSet. The reason is that not all the result beans need to be
* held in memory at the same time and instead processed one at a time.
* </p>
* <p>
* Internally this query using a PersistenceContext scoped to each bean (and the
* beans associated object graph).
* </p>
* <p>
* <pre>{@code
*
* ebeanServer.find(Order.class)
* .where().eq("status", Order.Status.NEW)
* .order().asc("id")
* .findEachWhile((Order order) -> {
*
* // do something with the order bean
* System.out.println(" -- processing order ... " + order);
*
* boolean carryOnProcessing = ...
* return carryOnProcessing;
* });
*
* }</pre>
*
* @see Query#findEach(Consumer)
* @see Query#findEachWhile(Predicate)
*/
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
/**
* Return versions of a @History entity bean.
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*/
@Nonnull
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
/**
* Execute a query returning a list of beans.
* <p>
* Generally you are able to use {@link Query#findList()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
* <p>
* <pre>{@code
*
* List<Customer> customers =
* ebeanServer.find(Customer.class)
* .where().ilike("name", "rob%")
* .findList();
*
* }</pre>
*
* @param <T> the type of entity bean to fetch.
* @param query the query to execute.
* @param transaction the transaction to use (can be null).
* @return the list of fetched beans.
* @see Query#findList()
*/
@Nonnull
<T> List<T> findList(Query<T> query, Transaction transaction);
/**
* Execute find row count query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @param query the query to execute the row count on
* @param transaction the transaction (can be null).
* @return a Future object for the row count query
* @see Query#findFutureCount()
*/
@Nonnull
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
/**
* Execute find Id's query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @param query the query to execute the fetch Id's on
* @param transaction the transaction (can be null).
* @return a Future object for the list of Id's
* @see Query#findFutureIds()
*/
@Nonnull
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
/**
* Execute find list query in a background thread returning a FutureList object.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a timeout).
* <p>
* This query will execute in it's own PersistenceContext and using its own transaction.
* What that means is that it will not share any bean instances with other queries.
*
* @param query the query to execute in the background
* @param transaction the transaction (can be null).
* @return a Future object for the list result of the query
* @see Query#findFutureList()
*/
@Nonnull
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
* The benefit of using this over findList() is that it provides functionality to get the
* total row count etc.
* </p>
* <p>
* If maxRows is not set on the query prior to calling findPagedList() then a
* PersistenceException is thrown.
* </p>
* <p>
* <pre>{@code
*
* PagedList<Order> pagedList = Ebean.find(Order.class)
* .setFirstRow(50)
* .setMaxRows(20)
* .findPagedList();
*
* // fetch the total row count in the background
* pagedList.loadRowCount();
*
* List<Order> orders = pagedList.getList();
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* @return The PagedList
* @see Query#findPagedList()
*/
@Nonnull
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
/**
* Execute the query returning a set of entity beans.
* <p>
* Generally you are able to use {@link Query#findSet()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
* <p>
* <pre>{@code
*
* Set<Customer> customers =
* ebeanServer.find(Customer.class)
* .where().ilike("name", "rob%")
* .findSet();
*
* }</pre>
*
* @param <T> the type of entity bean to fetch.
* @param query the query to execute
* @param transaction the transaction to use (can be null).
* @return the set of fetched beans.
* @see Query#findSet()
*/
@Nonnull
<T> Set<T> findSet(Query<T> query, Transaction transaction);
/**
* Execute the query returning the entity beans in a Map.
* <p>
* Generally you are able to use {@link Query#findMap()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
*
* @param <T> the type of entity bean to fetch.
* @param query the query to execute.
* @param transaction the transaction to use (can be null).
* @return the map of fetched beans.
* @see Query#findMap()
*/
@Nonnull
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
/**
* Execute the query returning a list of values for a single property.
* <p>
* <h3>Example 1:</h3>
* <pre>{@code
*
* List<String> names =
* Ebean.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .findSingleAttributeList();
*
* }</pre>
* <h3>Example 2:</h3>
* <pre>{@code
*
* List<String> names =
* Ebean.find(Customer.class)
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
* }</pre>
*
* @return the list of values for the selected property
* @see Query#findSingleAttributeList()
*/
@Nonnull
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
/**
* Execute the query returning at most one entity bean or null (if no matching
* bean is found).
* <p>
* This will throw a NonUniqueResultException if the query finds more than one result.
* </p>
* <p>
* Generally you are able to use {@link Query#findOne()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
*
* @param <T> the type of entity bean to fetch.
* @param query the query to execute.
* @param transaction the transaction to use (can be null).
* @return the list of fetched beans.
* @throws NonUniqueResultException if more than one result was found
* @see Query#findOne()
*/
@Nullable
<T> T findOne(Query<T> query, Transaction transaction);
/**
* Similar to findOne() but returns an Optional (rather than nullable).
*/
@Nonnull
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
/**
* Execute as a delete query deleting the 'root level' beans that match the predicates
* in the query.
* <p>
* Note that if the query includes joins then the generated delete statement may not be
* optimal depending on the database platform.
* </p>
*
* @param query the query used for the delete
* @param transaction the transaction to use (can be null)
* @param <T> the type of entity bean to fetch.
* @return the number of beans/rows that were deleted
*/
<T> int delete(Query<T> query, Transaction transaction);
/**
* Execute the update query returning the number of rows updated.
* <p>
* The update query must be created using {@link #update(Class)}.
* </p>
*
* @param query the update query to execute
* @param transaction the optional transaction to use for the update (can be null)
* @param <T> the type of entity bean
* @return The number of rows updated
*/
<T> int update(Query<T> query, Transaction transaction);
/**
* Execute the sql query returning a list of MapBean.
* <p>
* Generally you are able to use {@link SqlQuery#findList()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
*
* @param query the query to execute.
* @param transaction the transaction to use (can be null).
* @return the list of fetched MapBean.
* @see SqlQuery#findList()
*/
@Nonnull
List<SqlRow> findList(SqlQuery query, Transaction transaction);
/**
* Execute the SqlQuery iterating a row at a time.
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
/**
* Execute the SqlQuery iterating a row at a time with the ability to stop consuming part way through.
* <p>
* Returning false after processing a row stops the iteration through the query results.
* </p>
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
/**
* Execute the sql query returning a single MapBean or null.
* <p>
* This will throw a PersistenceException if the query found more than one
* result.
* </p>
* <p>
* Generally you are able to use {@link SqlQuery#findOne()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
*
* @param query the query to execute.
* @param transaction the transaction to use (can be null).
* @return the fetched MapBean or null if none was found.
* @see SqlQuery#findOne()
*/
@Nullable
SqlRow findOne(SqlQuery query, Transaction transaction);
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.api;
import io.ebean.DtoQuery;
import io.ebean.EbeanServer;
import io.ebean.ExtendedServer;
import io.ebean.PersistenceContextScope;
import io.ebean.Query;
import io.ebean.RowConsumer;
@@ -31,7 +32,7 @@ import java.util.function.Predicate;
/**
* Service Provider extension to EbeanServer.
*/
public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionLoader {
public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanLoader, BeanCollectionLoader {
/**
* Return the log manager.
@@ -8,6 +8,7 @@ import io.ebean.DocumentStore;
import io.ebean.DtoQuery;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebean.ExtendedServer;
import io.ebean.Filter;
import io.ebean.FutureIds;
import io.ebean.FutureList;
@@ -501,6 +502,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return serverName;
}
@Override
public ExtendedServer extended() {
return this;
}
@Override
public BeanState getBeanState(Object bean) {
if (bean instanceof EntityBean) {
@@ -1,8 +1,8 @@
package io.ebeaninternal.server.query;
import io.ebean.EbeanServer;
import io.ebean.PagedList;
import io.ebeaninternal.api.Monitor;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import javax.persistence.PersistenceException;
@@ -16,7 +16,7 @@ import java.util.concurrent.Future;
*/
public class LimitOffsetPagedList<T> implements PagedList<T> {
private final transient EbeanServer server;
private final transient SpiEbeanServer server;
private final SpiQuery<T> query;
@@ -35,7 +35,7 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
/**
* Construct with firstRow/maxRows.
*/
public LimitOffsetPagedList(EbeanServer server, SpiQuery<T> query) {
public LimitOffsetPagedList(SpiEbeanServer server, SpiQuery<T> query) {
this.server = server;
this.query = query;
this.maxRows = query.getMaxRows();