From e21839de91bef3f085e63dccc80f9bfd7f356bed Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 14 Jun 2018 11:03:29 +1200 Subject: [PATCH] #1424 - Deprecate / Move ... finder methods that take explicit transaction to ExtendedServer API --- src/main/java/io/ebean/EbeanServer.java | 58 +++ src/main/java/io/ebean/ExtendedServer.java | 438 ++++++++++++++++++ .../io/ebeaninternal/api/SpiEbeanServer.java | 3 +- .../server/core/DefaultServer.java | 6 + .../server/query/LimitOffsetPagedList.java | 6 +- .../java/io/ebean/ExtendedServerTest.java | 41 ++ .../ebeaninternal/api/TDSpiEbeanServer.java | 6 + .../query/LimitOffsetPagedListTest.java | 16 +- 8 files changed, 562 insertions(+), 12 deletions(-) create mode 100644 src/main/java/io/ebean/ExtendedServer.java create mode 100644 src/test/java/io/ebean/ExtendedServerTest.java diff --git a/src/main/java/io/ebean/EbeanServer.java b/src/main/java/io/ebean/EbeanServer.java index 23b974591..36e2612b4 100644 --- a/src/main/java/io/ebean/EbeanServer.java +++ b/src/main/java/io/ebean/EbeanServer.java @@ -808,22 +808,41 @@ public interface EbeanServer { T getReference(Class beanType, Object id); /** + * Return the extended API for EbeanServer. + *

+ * The extended API has the options for executing queries that take an explicit + * transaction as an argument. + *

+ *

+ * 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. + *

+ */ + 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 int findCount(Query 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 List findIds(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Return a QueryIterator for the query. *

* Generally using {@link #findEach(Query, Consumer, Transaction)} or @@ -841,9 +860,11 @@ public interface EbeanServer { * @see Query#findEachWhile(Predicate) */ @Nonnull + @Deprecated QueryIterator findIterate(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the query visiting the each bean one at a time. *

* 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 void findEach(Query query, Consumer consumer, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the query visiting the each bean one at a time. *

* 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 void findEachWhile(Query query, Predicate consumer, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Return versions of a @History entity bean. *

* Generally this query is expected to be a find by id or unique predicates query. @@ -918,9 +943,11 @@ public interface EbeanServer { *

*/ @Nonnull + @Deprecated List> findVersions(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute a query returning a list of beans. *

* Generally you are able to use {@link Query#findList()} rather than @@ -944,9 +971,11 @@ public interface EbeanServer { * @see Query#findList() */ @Nonnull + @Deprecated List findList(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute find row count query in a background thread. *

* 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 FutureRowCount findFutureCount(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute find Id's query in a background thread. *

* 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 FutureIds findFutureIds(Query 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. *

* 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 FutureList findFutureList(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Return a PagedList for this query using firstRow and maxRows. *

* 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 PagedList findPagedList(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the query returning a set of entity beans. *

* Generally you are able to use {@link Query#findSet()} rather than @@ -1051,9 +1088,11 @@ public interface EbeanServer { * @see Query#findSet() */ @Nonnull + @Deprecated Set findSet(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the query returning the entity beans in a Map. *

* Generally you are able to use {@link Query#findMap()} rather than @@ -1068,9 +1107,11 @@ public interface EbeanServer { * @see Query#findMap() */ @Nonnull + @Deprecated Map findMap(Query 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. *

*

Example 1:

@@ -1101,9 +1142,11 @@ public interface EbeanServer { * @see Query#findSingleAttributeList() */ @Nonnull + @Deprecated List
findSingleAttributeList(Query 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). *

@@ -1123,15 +1166,19 @@ public interface EbeanServer { * @see Query#findOne() */ @Nullable + @Deprecated T findOne(Query 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 Optional findOneOrEmpty(Query 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. *

@@ -1144,9 +1191,11 @@ public interface EbeanServer { * @param the type of entity bean to fetch. * @return the number of beans/rows that were deleted */ + @Deprecated int delete(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the update query returning the number of rows updated. *

* The update query must be created using {@link #update(Class)}. @@ -1157,9 +1206,11 @@ public interface EbeanServer { * @param the type of entity bean * @return The number of rows updated */ + @Deprecated int update(Query query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the sql query returning a list of MapBean. *

* Generally you are able to use {@link SqlQuery#findList()} rather than @@ -1173,17 +1224,21 @@ public interface EbeanServer { * @see SqlQuery#findList() */ @Nonnull + @Deprecated List findList(SqlQuery query, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the SqlQuery iterating a row at a time. *

* This streaming type query is useful for large query execution as only 1 row needs to be held in memory. *

*/ + @Deprecated void findEach(SqlQuery query, Consumer 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. *

* 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. *

*/ + @Deprecated void findEachWhile(SqlQuery query, Predicate consumer, Transaction transaction); /** + * Deprecated - Moved to the ExtendedServer API, please use via extended(). * Execute the sql query returning a single MapBean or null. *

* 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); /** diff --git a/src/main/java/io/ebean/ExtendedServer.java b/src/main/java/io/ebean/ExtendedServer.java new file mode 100644 index 000000000..1d3d6264f --- /dev/null +++ b/src/main/java/io/ebean/ExtendedServer.java @@ -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. + *

+ * This provides the finder methods that take an explicit transaction rather than obtaining + * the transaction from the usual mechanism (which is ThreadLocal based). + *

+ *

+ * 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. + *

+ *

+ * 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. + *

+ */ +public interface ExtendedServer { + + /** + * Return the number of 'top level' or 'root' entities this query should return. + * + * @see Query#findCount() + * @see Query#findFutureCount() + */ + int findCount(Query query, Transaction transaction); + + /** + * Return the Id values of the query as a List. + * + * @see Query#findIds() + */ + @Nonnull + List
findIds(Query query, Transaction transaction); + + /** + * Return a QueryIterator for the query. + *

+ * 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). + *

+ *

+ * 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. + *

+ * + * @see Query#findIterate() + * @see Query#findEach(Consumer) + * @see Query#findEachWhile(Predicate) + */ + @Nonnull + QueryIterator findIterate(Query query, Transaction transaction); + + /** + * Execute the query visiting the each bean one at a time. + *

+ * 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. + *

+ *

+ * Internally this query using a PersistenceContext scoped to each bean (and the + * beans associated object graph). + *

+ *

+ *

{@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);
+   *       });
+   *
+   * }
+ * + * @see Query#findEach(Consumer) + * @see Query#findEachWhile(Predicate) + */ + void findEach(Query query, Consumer consumer, Transaction transaction); + + /** + * Execute the query visiting the each bean one at a time. + *

+ * Compared to findEach() this provides the ability to stop processing the query + * results early by returning false for the Predicate. + *

+ *

+ * 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. + *

+ *

+ * Internally this query using a PersistenceContext scoped to each bean (and the + * beans associated object graph). + *

+ *

+ *

{@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;
+   *       });
+   *
+   * }
+ * + * @see Query#findEach(Consumer) + * @see Query#findEachWhile(Predicate) + */ + void findEachWhile(Query query, Predicate consumer, Transaction transaction); + + /** + * Return versions of a @History entity bean. + *

+ * 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. + *

+ */ + @Nonnull + List> findVersions(Query query, Transaction transaction); + + /** + * Execute a query returning a list of beans. + *

+ * 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. + *

+ *

+ *

{@code
+   *
+   * List customers =
+   *     ebeanServer.find(Customer.class)
+   *     .where().ilike("name", "rob%")
+   *     .findList();
+   *
+   * }
+ * + * @param 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 + List findList(Query query, Transaction transaction); + + /** + * Execute find row count query in a background thread. + *

+ * 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). + *

+ * + * @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 + FutureRowCount findFutureCount(Query query, Transaction transaction); + + /** + * Execute find Id's query in a background thread. + *

+ * 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). + *

+ * + * @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 + FutureIds findFutureIds(Query query, Transaction transaction); + + /** + * Execute find list query in a background thread returning a FutureList object. + *

+ * 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). + *

+ * 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 + FutureList findFutureList(Query query, Transaction transaction); + + /** + * Return a PagedList for this query using firstRow and maxRows. + *

+ * The benefit of using this over findList() is that it provides functionality to get the + * total row count etc. + *

+ *

+ * If maxRows is not set on the query prior to calling findPagedList() then a + * PersistenceException is thrown. + *

+ *

+ *

{@code
+   *
+   *  PagedList pagedList = Ebean.find(Order.class)
+   *       .setFirstRow(50)
+   *       .setMaxRows(20)
+   *       .findPagedList();
+   *
+   *       // fetch the total row count in the background
+   *       pagedList.loadRowCount();
+   *
+   *       List orders = pagedList.getList();
+   *       int totalRowCount = pagedList.getTotalRowCount();
+   *
+   * }
+ * + * @return The PagedList + * @see Query#findPagedList() + */ + @Nonnull + PagedList findPagedList(Query query, Transaction transaction); + + /** + * Execute the query returning a set of entity beans. + *

+ * 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. + *

+ *

+ *

{@code
+   *
+   * Set customers =
+   *     ebeanServer.find(Customer.class)
+   *     .where().ilike("name", "rob%")
+   *     .findSet();
+   *
+   * }
+ * + * @param 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 + Set findSet(Query query, Transaction transaction); + + /** + * Execute the query returning the entity beans in a Map. + *

+ * 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. + *

+ * + * @param 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 + Map findMap(Query query, Transaction transaction); + + /** + * Execute the query returning a list of values for a single property. + *

+ *

Example 1:

+ *
{@code
+   *
+   *  List names =
+   *    Ebean.find(Customer.class)
+   *      .select("name")
+   *      .orderBy().asc("name")
+   *      .findSingleAttributeList();
+   *
+   * }
+ *

Example 2:

+ *
{@code
+   *
+   *  List names =
+   *    Ebean.find(Customer.class)
+   *      .setDistinct(true)
+   *      .select("name")
+   *      .where().eq("status", Customer.Status.NEW)
+   *      .orderBy().asc("name")
+   *      .setMaxRows(100)
+   *      .findSingleAttributeList();
+   *
+   * }
+ * + * @return the list of values for the selected property + * @see Query#findSingleAttributeList() + */ + @Nonnull + List
findSingleAttributeList(Query query, Transaction transaction); + + /** + * Execute the query returning at most one entity bean or null (if no matching + * bean is found). + *

+ * This will throw a NonUniqueResultException if the query finds more than one result. + *

+ *

+ * 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. + *

+ * + * @param 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 findOne(Query query, Transaction transaction); + + /** + * Similar to findOne() but returns an Optional (rather than nullable). + */ + @Nonnull + Optional findOneOrEmpty(Query query, Transaction transaction); + + /** + * Execute as a delete query deleting the 'root level' beans that match the predicates + * in the query. + *

+ * Note that if the query includes joins then the generated delete statement may not be + * optimal depending on the database platform. + *

+ * + * @param query the query used for the delete + * @param transaction the transaction to use (can be null) + * @param the type of entity bean to fetch. + * @return the number of beans/rows that were deleted + */ + int delete(Query query, Transaction transaction); + + /** + * Execute the update query returning the number of rows updated. + *

+ * The update query must be created using {@link #update(Class)}. + *

+ * + * @param query the update query to execute + * @param transaction the optional transaction to use for the update (can be null) + * @param the type of entity bean + * @return The number of rows updated + */ + int update(Query query, Transaction transaction); + + /** + * Execute the sql query returning a list of MapBean. + *

+ * 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. + *

+ * + * @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 findList(SqlQuery query, Transaction transaction); + + /** + * Execute the SqlQuery iterating a row at a time. + *

+ * This streaming type query is useful for large query execution as only 1 row needs to be held in memory. + *

+ */ + void findEach(SqlQuery query, Consumer consumer, Transaction transaction); + + /** + * Execute the SqlQuery iterating a row at a time with the ability to stop consuming part way through. + *

+ * Returning false after processing a row stops the iteration through the query results. + *

+ *

+ * This streaming type query is useful for large query execution as only 1 row needs to be held in memory. + *

+ */ + void findEachWhile(SqlQuery query, Predicate consumer, Transaction transaction); + + /** + * Execute the sql query returning a single MapBean or null. + *

+ * This will throw a PersistenceException if the query found more than one + * result. + *

+ *

+ * 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. + *

+ * + * @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); + +} diff --git a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java index af0154a8e..1971b4b24 100644 --- a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java +++ b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java @@ -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. diff --git a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 3032a343d..307cc3d44 100644 --- a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -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) { diff --git a/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java b/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java index 4b4f34c09..b4496a56e 100644 --- a/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java +++ b/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java @@ -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 implements PagedList { - private final transient EbeanServer server; + private final transient SpiEbeanServer server; private final SpiQuery query; @@ -35,7 +35,7 @@ public class LimitOffsetPagedList implements PagedList { /** * Construct with firstRow/maxRows. */ - public LimitOffsetPagedList(EbeanServer server, SpiQuery query) { + public LimitOffsetPagedList(SpiEbeanServer server, SpiQuery query) { this.server = server; this.query = query; this.maxRows = query.getMaxRows(); diff --git a/src/test/java/io/ebean/ExtendedServerTest.java b/src/test/java/io/ebean/ExtendedServerTest.java new file mode 100644 index 000000000..aef467e69 --- /dev/null +++ b/src/test/java/io/ebean/ExtendedServerTest.java @@ -0,0 +1,41 @@ +package io.ebean; + +import org.junit.Test; +import org.tests.model.basic.Customer; +import org.tests.model.basic.ResetBasicData; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ExtendedServerTest extends BaseTestCase { + + @Test + public void findList() { + + ResetBasicData.reset(); + + EbeanServer server = Ebean.getDefaultServer(); + + Query query = server.find(Customer.class) + .where().startsWith("name", "Rob") + .query(); + + // rather than use .findList() return the query + // when we use findList() .. it obtains a transaction using + // the normal mechanism + + // obtain a transaction somehow ... + // for this test/example we just begin one + try (Transaction transaction = server.beginTransaction()) { + + // obtain extended API ... such that we can execute the + // query using an explicit transaction + List customers = server.extended().findList(query, transaction); + + assertThat(customers).isNotEmpty(); + transaction.commit(); + } + } + +} diff --git a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java index 64bff0d26..c83e84eb8 100644 --- a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java +++ b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java @@ -7,6 +7,7 @@ import io.ebean.CallableSql; import io.ebean.DocumentStore; import io.ebean.DtoQuery; import io.ebean.ExpressionFactory; +import io.ebean.ExtendedServer; import io.ebean.Filter; import io.ebean.FutureIds; import io.ebean.FutureList; @@ -79,6 +80,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer { this.name = name; } + @Override + public ExtendedServer extended() { + return this; + } + @Override public SpiLogManager log() { return null; diff --git a/src/test/java/io/ebeaninternal/server/query/LimitOffsetPagedListTest.java b/src/test/java/io/ebeaninternal/server/query/LimitOffsetPagedListTest.java index f2f5d4a53..d7de421c7 100644 --- a/src/test/java/io/ebeaninternal/server/query/LimitOffsetPagedListTest.java +++ b/src/test/java/io/ebeaninternal/server/query/LimitOffsetPagedListTest.java @@ -1,19 +1,19 @@ package io.ebeaninternal.server.query; -import io.ebean.Ebean; -import io.ebean.EbeanServer; +import io.ebean.BaseTestCase; +import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.api.SpiQuery; -import org.tests.model.basic.Order; import org.junit.Test; +import org.tests.model.basic.Order; import static org.junit.Assert.assertEquals; -public class LimitOffsetPagedListTest { +public class LimitOffsetPagedListTest extends BaseTestCase { - private EbeanServer server = Ebean.getDefaultServer(); + private SpiEbeanServer server = spiEbeanServer(); @Test - public void getPageIndex_when_firstRowsZero() throws Exception { + public void getPageIndex_when_firstRowsZero() { assertEquals(limit(0, 10).getPageIndex(), 0); } @@ -28,12 +28,12 @@ public class LimitOffsetPagedListTest { } @Test - public void getPageIndex_when_1_10() throws Exception { + public void getPageIndex_when_1_10() { assertEquals(limit(1, 10).getPageIndex(), 1); } @Test - public void getPageIndex_when_9_10() throws Exception { + public void getPageIndex_when_9_10() { assertEquals(limit(1, 10).getPageIndex(), 1); }