From 0aad285f3541cce5b7c2e695d19711f65781cecc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 2 Dec 2016 21:47:30 +1300 Subject: [PATCH] #907 - Remove Model.Finder ... migrate to Finder --- src/main/java/com/avaje/ebean/Model.java | 623 +----------------- .../avaje/tests/model/info/InfoCompany.java | 1 + .../avaje/tests/model/info/InfoCustomer.java | 1 + .../avaje/tests/model/onetoone/Account.java | 4 +- .../TestOneToOneOptionalRelationship.java | 2 +- .../com/avaje/tests/model/onetoone/User.java | 4 +- .../tests/model/onetoone/album/Album.java | 4 +- .../tests/model/onetoone/album/Cover.java | 1 + .../album/TestOneToOneHardDelete.java | 4 +- 9 files changed, 17 insertions(+), 627 deletions(-) diff --git a/src/main/java/com/avaje/ebean/Model.java b/src/main/java/com/avaje/ebean/Model.java index 711075c59..1fbd81f44 100644 --- a/src/main/java/com/avaje/ebean/Model.java +++ b/src/main/java/com/avaje/ebean/Model.java @@ -1,16 +1,8 @@ package com.avaje.ebean; import com.avaje.ebean.bean.EntityBean; -import com.avaje.ebean.util.ClassUtil; -import org.jetbrains.annotations.Nullable; import javax.persistence.MappedSuperclass; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.function.Consumer; -import java.util.function.Predicate; /** * A MappedSuperclass base class that provides convenience methods for inserting, updating and @@ -19,7 +11,7 @@ import java.util.function.Predicate; * By having your entity beans extend this it provides a 'Active Record' style programming model for * Ebean users. *

- * Note that there is a avaje-ebeanorm-mocker project that enables you to use Mockito or similar + * Note that there is a ebean-mocker project that enables you to use Mockito or similar * tools to still mock out the underlying 'default EbeanServer' for testing purposes. *

* You may choose not use this Model mapped superclass if you don't like the 'Active Record' style @@ -32,7 +24,7 @@ import java.util.function.Predicate; * that same instance also used to support the Model and Finder active record style. *

* If you choose to use the Model mapped superclass you will probably also chose to additionally add - * a {@link Find} as a public static field to complete the active record pattern and provide a + * a {@link Finder} as a public static field to complete the active record pattern and provide a * relatively nice clean way to write queries. *

*

Typical common @MappedSuperclass

@@ -48,9 +40,9 @@ import java.util.function.Predicate; * * @Version Long version; * - * @CreatedTimestamp Timestamp whenCreated; + * @WhenCreated Timestamp whenCreated; * - * @UpdatedTimestamp Timestamp whenUpdated; + * @WhenUpdated Timestamp whenUpdated; * * ... * @@ -61,15 +53,9 @@ import java.util.function.Predicate; * * // Extend the mappedSuperclass * - * @Entity @Table(name="oto_account") + * @Entity @Table(name="o_account") * public class Customer extends BaseModel { * - * // Add a static Find - * // ... with Long being the type of our @Id property. - * // ... Note the {} at the end as Find is an abstract class. - * - * public static final Find find = new Find(){}; - * * String name; * ... * } @@ -87,25 +73,6 @@ import java.util.function.Predicate; * customer.save(); * * } - *

- *

Find byId

- *
{@code
- *
- *     // find byId
- *     Customer customer = Customer.find.byId(42);
- *
- * }
- *

- *

Find where

- *
{@code
- *
- *     // find where ...
- *     List customers =
- *         Customer.find
- *         .where().gt("startDate", lastMonth)
- *         .findList();
- *
- * }
*/ @MappedSuperclass public abstract class Model { @@ -305,584 +272,4 @@ public abstract class Model { db().refresh(this); } - /** - * A concrete implementation of Find. - *

- * It should be preferred to use {@link Find} instead of Finder as that can use reflection to determine the class - * literal type of the entity bean. - *

- * - * @param type of the Id property - * @param type of the entity bean - */ - public static class Finder extends Find { - - /** - * Create with the type of the entity bean. - *

- *

{@code
-     *
-     * @Entity
-     * public class Customer extends BaseModel {
-     *
-     *   public static final Finder find = new Finder(Customer.class);
-     *   ...
-     *
-     * }
- *

- *

- * The preferred approach is to instead use Find as below. This approach is more DRY in that it does - * not require the class literal Customer.class to be passed into the constructor. - *

- *

{@code
-     *
-     * @Entity
-     * public class Customer extends BaseModel {
-     *
-     *   public static final Find find = new Find(){};
-     *   ...
-     *
-     * }
- */ - public Finder(Class type) { - super(null, type); - } - - /** - * Create with the type of the entity bean and specific server name. - */ - public Finder(String serverName, Class type) { - super(serverName, type); - } - - } - - /** - * Helper object for performing queries. - *

- *

- * Typically a Find instance is defined as a public static field on an entity bean class to provide a - * nice way to write queries. - *

- *

Example use:

- *

- *

{@code
-   *
-   * @Entity
-   * public class Customer extends BaseModel {
-   *
-   *   public static final Find find = new Find(){};
-   *
-   *   ...
-   *
-   * }
- *

- * This enables you to write code like: - *

{@code
-   *
-   * Customer customer = Customer.find.byId(42L);
-   *
-   * List customers =
-   *     Customer.find
-   *         .select("name, dateOfBirth")
-   *         .findList();
-   *
-   * }
- *

- *

Kotlin

- * In Kotlin you would typically create Find as a companion object. - *
{@code
-   *
-   *   // kotlin
-   *   companion object : Model.Find() {}
-   *
-   * }
- * - * @param The Id type. This is most often a {@link Long} but is also often a {@link UUID} or - * {@link String}. - * @param The entity bean type - */ - public static abstract class Find { - - /** - * The entity bean type. - */ - private final Class type; - - /** - * The name of the EbeanServer, null for the default server. - */ - private final String serverName; - - /** - * Creates a finder for entity of type T with ID of type I. - *

- * Typically you create Find as a public static field on each entity bean as the example below. - *

- *

- * Note that Find is an abstract class and hence {} is required. This is done so - * that the type (class literal) of the entity bean can be derived from the generics parameter. - *

- *

{@code
-     *
-     * @Entity
-     * public class Customer extends BaseModel {
-     *
-     *   // Note the trailing {} as Find is an abstract class.
-     *   // We do this so that we can derive the type literal Customer.class
-     *   // via reflection
-     *   public static final Find find = new Find(){};
-     *   ...
-     *
-     * }
- *

- * This enables you to write code like: - *

{@code
-     *
-     * Customer customer = Customer.find.byId(42L);
-     *
-     * List customers =
-     *     Customer.find
-     *        .select("name, email, dateOfBirth")
-     *        .findList();
-     *
-     * }
- *

- *

Kotlin

- * In Kotlin you would typically create it as a companion object. - *

- *

{@code
-     *
-     *   // kotlin
-     *   companion object : Model.Find() {}
-     *
-     * }
- */ - @SuppressWarnings("unchecked") - public Find() { - this.serverName = null; - this.type = (Class) ClassUtil.getSecondArgumentType(getClass()); - } - - /** - * Construct passing the class literal type of the entity type. - */ - protected Find(String serverName, Class type) { - this.serverName = serverName; - this.type = type; - } - - /** - * Return the underlying 'default' EbeanServer. - *

- *

- * This provides full access to the API such as explicit transaction demarcation etc. - */ - public EbeanServer db() { - return Ebean.getServer(serverName); - } - - /** - * Return typically a different EbeanServer to the default. - *

- * This is equivalent to {@link Ebean#getServer(String)} - * - * @param server The name of the EbeanServer. If this is null then the default EbeanServer is - * returned. - */ - public EbeanServer db(String server) { - return Ebean.getServer(server); - } - - /** - * Creates a Finder for the named EbeanServer. - *

- *

- * Create and return a new Finder for a different server. - */ - public Finder on(String server) { - return new Finder<>(server, type); - } - - /** - * Delete a bean by Id. - *

- * Equivalent to {@link EbeanServer#delete(Class, Object)} - */ - public void deleteById(I id) { - db().delete(type, id); - } - - /** - * Retrieves all entities of the given type. - *

- *

- * This is the same as (synonym for) {@link #findList()} - */ - public List all() { - return findList(); - } - - /** - * Retrieves an entity by ID. - *

- *

- * Equivalent to {@link EbeanServer#find(Class, Object)} - */ - @Nullable - public T byId(I id) { - return db().find(type, id); - } - - /** - * Creates an entity reference for this ID. - *

- *

- * Equivalent to {@link EbeanServer#getReference(Class, Object)} - */ - public T ref(I id) { - return db().getReference(type, id); - } - - /** - * Creates a filter for sorting and filtering lists of entities locally without going back to - * the database. - *

- * Equivalent to {@link EbeanServer#filter(Class)} - */ - public Filter filter() { - return db().filter(type); - } - - /** - * Creates a query. - *

- * Equivalent to {@link EbeanServer#find(Class)} - */ - public Query query() { - return db().find(type); - } - - /** - * Creates a query applying the path properties to set the select and fetch clauses. - *

- * Equivalent to {@link Query#apply(FetchPath)} - */ - public Query apply(FetchPath fetchPath) { - return db().find(type).apply(fetchPath); - } - - /** - * Returns the next identity value. - * - * @see EbeanServer#nextId(Class) - */ - @SuppressWarnings("unchecked") - public I nextId() { - return (I) db().nextId(type); - } - - /** - * Executes a query and returns the results as a list of IDs. - *

- * Equivalent to {@link Query#findIds()} - */ - public List findIds() { - return query().findIds(); - } - - /** - * Execute the query consuming each bean one at a time. - *

- * This is generally used to process large queries where unlike findList - * you do not want to hold all the results in memory at once but instead - * process them one at a time (requiring far less memory). - *

- * Equivalent to {@link Query#findEach(Consumer)} - */ - public void findEach(Consumer consumer) { - query().findEach(consumer); - } - - /** - * Execute the query consuming each bean one at a time. - *

- * Equivalent to {@link Query#findEachWhile(Predicate)} - *

- * This is similar to #findEach except that you return boolean - * true to continue processing beans and return false to stop - * processing early. - *

- *

- * This is generally used to process large queries where unlike findList - * you do not want to hold all the results in memory at once but instead - * process them one at a time (requiring far less memory). - *

- * Equivalent to {@link Query#findEachWhile(Predicate)} - */ - public void findEachWhile(Predicate consumer) { - query().findEachWhile(consumer); - } - - /** - * Retrieves all entities of the given type. - *

- * The same as {@link #all()} - *

- * Equivalent to {@link Query#findList()} - */ - public List findList() { - return query().findList(); - } - - /** - * Returns all the entities of the given type as a set. - *

- * Equivalent to {@link Query#findSet()} - */ - public Set findSet() { - return query().findSet(); - } - - /** - * Retrieves all entities of the given type as a map of objects. - *

- * Equivalent to {@link Query#findMap()} - */ - public Map findMap() { - return query().findMap(); - } - - /** - * Executes a find row count query in a background thread. - *

- * Equivalent to {@link Query#findFutureCount()} - */ - public FutureRowCount findFutureCount() { - return query().findFutureCount(); - } - - /** - * Deprecated in favor of findFutureCount(). - *

- * Equivalent to {@link Query#findFutureCount()} - */ - public FutureRowCount findFutureRowCount() { - return query().findFutureCount(); - } - - /** - * Returns the total number of entities for this type. * - *

- * Equivalent to {@link Query#findCount()} - */ - public int findCount() { - return query().findCount(); - } - - /** - * Deprecated in favor of findCount(). - * - * @deprecated - */ - public int findRowCount() { - return query().findCount(); - } - - /** - * Returns the ExpressionFactory used by this query. - */ - public ExpressionFactory getExpressionFactory() { - return query().getExpressionFactory(); - } - - /** - * Explicitly sets a comma delimited list of the properties to fetch on the 'main' entity bean, - * to load a partial object. - *

- * Equivalent to {@link Query#select(String)} - */ - public Query select(String fetchProperties) { - return query().select(fetchProperties); - } - - /** - * Specifies a path to load including all its properties. - *

- * Equivalent to {@link Query#fetch(String)} - */ - public Query fetch(String path) { - return query().fetch(path); - } - - /** - * Additionally specifies a FetchConfig to specify a 'query join' and/or define the - * lazy loading query. - *

- * Equivalent to {@link Query#fetch(String, FetchConfig)} - */ - public Query fetch(String path, FetchConfig joinConfig) { - return query().fetch(path, joinConfig); - } - - /** - * Specifies a path to fetch with a specific list properties to include, to load a partial - * object. - *

- * Equivalent to {@link Query#fetch(String, String)} - */ - public Query fetch(String path, String fetchProperties) { - return query().fetch(path, fetchProperties); - } - - /** - * Additionally specifies a FetchConfig to use a separate query or lazy loading to - * load this path. - *

- * Equivalent to {@link Query#fetch(String, String, FetchConfig)} - */ - public Query fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig) { - return query().fetch(assocProperty, fetchProperties, fetchConfig); - } - - /** - * Adds expressions to the where clause with the ability to chain on the - * ExpressionList. - *

- * Equivalent to {@link Query#where()} - */ - public ExpressionList where() { - return query().where(); - } - - /** - * Returns the order by clause so that you can append an ascending or descending - * property to the order by clause. - *

- * This is exactly the same as {@link #orderBy}. - *

- * Equivalent to {@link Query#order()} - */ - public OrderBy order() { - return query().order(); - } - - /** - * Sets the order by clause, replacing the existing order by clause if - * there is one. - *

- * This is exactly the same as {@link #orderBy(String)}. - */ - public Query order(String orderByClause) { - return query().order(orderByClause); - } - - /** - * Returns the order by clause so that you can append an ascending or descending - * property to the order by clause. - *

- * This is exactly the same as {@link #order}. - *

- * Equivalent to {@link Query#orderBy()} - */ - public OrderBy orderBy() { - return query().orderBy(); - } - - /** - * Set the order by clause replacing the existing order by clause if - * there is one. - *

- * This is exactly the same as {@link #order(String)}. - */ - public Query orderBy(String orderByClause) { - return query().orderBy(orderByClause); - } - - /** - * Sets the first row to return for this query. - *

- * Equivalent to {@link Query#setFirstRow(int)} - */ - public Query setFirstRow(int firstRow) { - return query().setFirstRow(firstRow); - } - - /** - * Sets the maximum number of rows to return in the query. - *

- * Equivalent to {@link Query#setMaxRows(int)} - */ - public Query setMaxRows(int maxRows) { - return query().setMaxRows(maxRows); - } - - /** - * Sets the ID value to query. - *

- *

- * Use this to perform a find byId query but with additional control over the query such as - * using select and fetch to control what parts of the object graph are returned. - *

- * Equivalent to {@link Query#setId(Object)} - */ - public Query setId(Object id) { - return query().setId(id); - } - - /** - * Create and return a new query based on the RawSql. - *

- * Equivalent to {@link Query#setRawSql(RawSql)} - */ - public Query setRawSql(RawSql rawSql) { - return query().setRawSql(rawSql); - } - - /** - * Create a query with explicit 'AutoTune' use. - */ - public Query setAutoTune(boolean autoTune) { - return query().setAutoTune(autoTune); - } - - /** - * Create a query with the select with "for update" specified. - *

- *

- * This will typically create row level database locks on the selected rows. - */ - public Query setForUpdate(boolean forUpdate) { - return query().setForUpdate(forUpdate); - } - - /** - * Create a query specifying whether the returned beans will be read-only. - */ - public Query setReadOnly(boolean readOnly) { - return query().setReadOnly(readOnly); - } - - /** - * Create a query specifying if the beans should be loaded into the L2 cache. - */ - public Query setLoadBeanCache(boolean loadBeanCache) { - return query().setLoadBeanCache(loadBeanCache); - } - - /** - * Create a query specifying if the L2 bean cache should be used. - */ - public Query setUseCache(boolean useBeanCache) { - return query().setUseCache(useBeanCache); - } - - /** - * Create a query specifying if the L2 query cache should be used. - */ - public Query setUseQueryCache(boolean useQueryCache) { - return query().setUseQueryCache(useQueryCache); - } - - } } diff --git a/src/test/java/com/avaje/tests/model/info/InfoCompany.java b/src/test/java/com/avaje/tests/model/info/InfoCompany.java index 27c84f35b..97738d628 100644 --- a/src/test/java/com/avaje/tests/model/info/InfoCompany.java +++ b/src/test/java/com/avaje/tests/model/info/InfoCompany.java @@ -1,5 +1,6 @@ package com.avaje.tests.model.info; +import com.avaje.ebean.Finder; import com.avaje.ebean.Model; import com.avaje.ebean.annotation.JsonIgnore; diff --git a/src/test/java/com/avaje/tests/model/info/InfoCustomer.java b/src/test/java/com/avaje/tests/model/info/InfoCustomer.java index f0453c216..0f9111a1f 100644 --- a/src/test/java/com/avaje/tests/model/info/InfoCustomer.java +++ b/src/test/java/com/avaje/tests/model/info/InfoCustomer.java @@ -1,5 +1,6 @@ package com.avaje.tests.model.info; +import com.avaje.ebean.Finder; import com.avaje.ebean.Model; import javax.persistence.CascadeType; diff --git a/src/test/java/com/avaje/tests/model/onetoone/Account.java b/src/test/java/com/avaje/tests/model/onetoone/Account.java index cb993a4ef..5ed1025fa 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/Account.java +++ b/src/test/java/com/avaje/tests/model/onetoone/Account.java @@ -1,5 +1,6 @@ package com.avaje.tests.model.onetoone; +import com.avaje.ebean.Finder; import com.avaje.tests.model.BaseModel; import javax.persistence.Entity; @@ -10,8 +11,7 @@ import javax.persistence.Table; @Table(name = "oto_account") public class Account extends BaseModel { - public static final Find find = new Find() { - }; + public static final Finder find = new Finder<>(Account.class); String name; diff --git a/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneOptionalRelationship.java b/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneOptionalRelationship.java index 8b8b88ba4..bb634acf5 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneOptionalRelationship.java +++ b/src/test/java/com/avaje/tests/model/onetoone/TestOneToOneOptionalRelationship.java @@ -87,7 +87,7 @@ public class TestOneToOneOptionalRelationship extends BaseTestCase { LoggedSqlCollector.start(); - Account fetchedAccount = Account.find.fetch("user").setId(account.getId()).findUnique(); + Account fetchedAccount = Account.find.query().fetch("user").setId(account.getId()).findUnique(); Assert.assertNotNull(fetchedAccount); Assert.assertNotNull(fetchedAccount.getUser()); diff --git a/src/test/java/com/avaje/tests/model/onetoone/User.java b/src/test/java/com/avaje/tests/model/onetoone/User.java index 30d8f0c1c..f5b115284 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/User.java +++ b/src/test/java/com/avaje/tests/model/onetoone/User.java @@ -1,5 +1,6 @@ package com.avaje.tests.model.onetoone; +import com.avaje.ebean.Finder; import com.avaje.tests.model.BaseModel; import javax.persistence.Entity; @@ -10,8 +11,7 @@ import javax.persistence.Table; @Table(name = "oto_user") public class User extends BaseModel { - public static final Find find = new Find() { - }; + public static final Finder find = new Finder<>(User.class); String name; diff --git a/src/test/java/com/avaje/tests/model/onetoone/album/Album.java b/src/test/java/com/avaje/tests/model/onetoone/album/Album.java index faf16d6a2..2020ee449 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/album/Album.java +++ b/src/test/java/com/avaje/tests/model/onetoone/album/Album.java @@ -1,6 +1,6 @@ package com.avaje.tests.model.onetoone.album; -import com.avaje.ebean.Model; +import com.avaje.ebean.Finder; import javax.persistence.CascadeType; import javax.persistence.Entity; @@ -10,7 +10,7 @@ import javax.persistence.OneToOne; @Entity public class Album extends BaseModel { - public static final Model.Finder find = new Model.Finder<>(Album.class); + public static final Finder find = new Finder<>(Album.class); private String name; diff --git a/src/test/java/com/avaje/tests/model/onetoone/album/Cover.java b/src/test/java/com/avaje/tests/model/onetoone/album/Cover.java index e2b097bb8..6c6244d6f 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/album/Cover.java +++ b/src/test/java/com/avaje/tests/model/onetoone/album/Cover.java @@ -1,5 +1,6 @@ package com.avaje.tests.model.onetoone.album; +import com.avaje.ebean.Finder; import com.avaje.ebean.Model; import com.avaje.ebean.annotation.SoftDelete; import org.slf4j.Logger; diff --git a/src/test/java/com/avaje/tests/model/onetoone/album/TestOneToOneHardDelete.java b/src/test/java/com/avaje/tests/model/onetoone/album/TestOneToOneHardDelete.java index 4a3d94188..ddfbdb966 100644 --- a/src/test/java/com/avaje/tests/model/onetoone/album/TestOneToOneHardDelete.java +++ b/src/test/java/com/avaje/tests/model/onetoone/album/TestOneToOneHardDelete.java @@ -23,7 +23,7 @@ public class TestOneToOneHardDelete extends BaseTestCase { album.setCover(cover); album.save(); - Album found1 = Album.find.where().findUnique(); + Album found1 = Album.find.byId(album.getId()); LoggedSqlCollector.start(); @@ -40,7 +40,7 @@ public class TestOneToOneHardDelete extends BaseTestCase { assertThat(sql.get(1)).contains("update album set deleted=?, last_update=? where id=?"); assertThat(sql.get(2)).contains("update cover set deleted=? where id=?"); - Album found2 = Album.find.where().setIncludeSoftDeletes().findUnique(); + Album found2 = Album.find.query().setId(album.getId()).setIncludeSoftDeletes().findUnique(); LoggedSqlCollector.start();