diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index ce3ba3688..0a2a3b777 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.8.1-SNAPSHOT + 12.10.0-SNAPSHOT ebean api @@ -50,7 +50,7 @@ io.ebean ebean-annotation - 6.15 + 7.0 diff --git a/ebean-api/src/main/java/io/ebean/CancelableQuery.java b/ebean-api/src/main/java/io/ebean/CancelableQuery.java new file mode 100644 index 000000000..fb3100bd2 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/CancelableQuery.java @@ -0,0 +1,19 @@ +package io.ebean; + +/** + * Defines a cancelable query. + *

+ * Typically holds a representation of the PreparedStatement to perform the + * actual cancel. + *

+ */ +public interface CancelableQuery { + + /** + * Cancel the query. + *

+ * For JDBC this translates to calling cancel on the PreparedStatement. + *

+ */ + void cancel(); +} diff --git a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java index 6ad7b1d89..4aace866a 100644 --- a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java +++ b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java @@ -78,7 +78,7 @@ public class DatabaseFactory { Database server = createInternal(config); if (config.isRegister()) { if (config.isDefaultServer()) { - if (defaultServerName != null) { + if (defaultServerName != null && !defaultServerName.equals(config.getName())) { throw new IllegalStateException("Registering [" + config.getName() + "] as the default server but [" + defaultServerName + "] is already registered as the default"); } defaultServerName = config.getName(); diff --git a/ebean-api/src/main/java/io/ebean/DtoQuery.java b/ebean-api/src/main/java/io/ebean/DtoQuery.java index 33f439b93..69ed034ef 100644 --- a/ebean-api/src/main/java/io/ebean/DtoQuery.java +++ b/ebean-api/src/main/java/io/ebean/DtoQuery.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.Stream; /** * Query for performing native SQL queries that return DTO Bean's. @@ -37,7 +38,7 @@ import java.util.function.Predicate; * * } */ -public interface DtoQuery { +public interface DtoQuery extends CancelableQuery { /** * Execute the query returning a list. @@ -45,6 +46,26 @@ public interface DtoQuery { @Nonnull List findList(); + /** + * Execute the query iterating a row at a time. + *

+ * Note that the QueryIterator holds resources related to the underlying + * resultSet and potentially connection and MUST be closed. We should use + * QueryIterator in a try with resource block. + */ + @Nonnull + QueryIterator findIterate(); + + /** + * Execute the query returning a Stream. + *

+ * Note that the Stream holds resources related to the underlying + * resultSet and potentially connection and MUST be closed. We should use + * the Stream in a try with resource block. + */ + @Nonnull + Stream findStream(); + /** * Execute the query iterating a row at a time. *

diff --git a/ebean-api/src/main/java/io/ebean/ExpressionList.java b/ebean-api/src/main/java/io/ebean/ExpressionList.java index 72f1c06f9..e91846e08 100644 --- a/ebean-api/src/main/java/io/ebean/ExpressionList.java +++ b/ebean-api/src/main/java/io/ebean/ExpressionList.java @@ -1671,7 +1671,7 @@ public interface ExpressionList { ExpressionList endAnd(); /** - * End a AND junction - synonym for endJunction(). + * End a OR junction - synonym for endJunction(). */ ExpressionList endOr(); diff --git a/ebean-api/src/main/java/io/ebean/OrderBy.java b/ebean-api/src/main/java/io/ebean/OrderBy.java index 820a76314..8b39fc19e 100644 --- a/ebean-api/src/main/java/io/ebean/OrderBy.java +++ b/ebean-api/src/main/java/io/ebean/OrderBy.java @@ -16,7 +16,7 @@ import java.util.Objects; * on the Query object. *

*/ -public final class OrderBy implements Serializable { +public class OrderBy implements Serializable { private static final long serialVersionUID = 9157089257745730539L; @@ -69,7 +69,6 @@ public final class OrderBy implements Serializable { * Add a property with ascending order to this OrderBy. */ public Query asc(String propertyName) { - list.add(new Property(propertyName, true)); return query; } @@ -98,7 +97,6 @@ public final class OrderBy implements Serializable { return query; } - /** * Return true if the property is known to be contained in the order by clause. */ @@ -207,7 +205,6 @@ public final class OrderBy implements Serializable { if (!(obj instanceof OrderBy)) { return false; } - OrderBy e = (OrderBy) obj; return e.list.equals(list); } @@ -249,7 +246,7 @@ public final class OrderBy implements Serializable { /** * A property and its ascending descending order. */ - public static final class Property implements Serializable { + public static class Property implements Serializable { private static final long serialVersionUID = 1546009780322478077L; @@ -415,13 +412,10 @@ public final class OrderBy implements Serializable { } private void parse(String orderByClause) { - if (orderByClause == null) { return; } - - String[] chunks = orderByClause.split(","); - for (String chunk : chunks) { + for (String chunk : orderByClause.split(",")) { Property p = parseProperty(chunk); if (p != null) { list.add(p); @@ -467,8 +461,7 @@ public final class OrderBy implements Serializable { if (s.startsWith("desc")) { return false; } - String m = "Expecting [" + s + "] to be asc or desc?"; - throw new RuntimeException(m); + throw new RuntimeException("Expecting [" + s + "] to be asc or desc?"); } private boolean isEmptyString(String s) { diff --git a/ebean-api/src/main/java/io/ebean/Query.java b/ebean-api/src/main/java/io/ebean/Query.java index db7bf8cb9..0dc86905e 100644 --- a/ebean-api/src/main/java/io/ebean/Query.java +++ b/ebean-api/src/main/java/io/ebean/Query.java @@ -177,7 +177,7 @@ import java.util.stream.Stream; * * @param the type of Entity bean this query will fetch. */ -public interface Query { +public interface Query extends CancelableQuery { /** * The lock type (strength) to use with query FOR UPDATE row locking. @@ -291,15 +291,6 @@ public interface Query { */ UpdateQuery asUpdate(); - /** - * Cancel the query execution if supported by the underlying database and - * driver. - *

- * This must be called from a different thread to the query executor. - *

- */ - void cancel(); - /** * Return a copy of the query. *

diff --git a/ebean-api/src/main/java/io/ebean/QueryIterator.java b/ebean-api/src/main/java/io/ebean/QueryIterator.java index c158e62c6..6ad523151 100644 --- a/ebean-api/src/main/java/io/ebean/QueryIterator.java +++ b/ebean-api/src/main/java/io/ebean/QueryIterator.java @@ -56,7 +56,7 @@ import java.util.Iterator; * * @param the type of entity bean in the iteration */ -public interface QueryIterator extends Iterator, java.io.Closeable { +public interface QueryIterator extends Iterator, AutoCloseable { /** * Returns true if the iteration has more elements. @@ -70,12 +70,6 @@ public interface QueryIterator extends Iterator, java.io.Closeable { @Override T next(); - /** - * Remove is not allowed. - */ - @Override - void remove(); - /** * Close the underlying resources held by this iterator. */ diff --git a/ebean-api/src/main/java/io/ebean/SqlQuery.java b/ebean-api/src/main/java/io/ebean/SqlQuery.java index 8b5452ee7..9a878f233 100644 --- a/ebean-api/src/main/java/io/ebean/SqlQuery.java +++ b/ebean-api/src/main/java/io/ebean/SqlQuery.java @@ -37,7 +37,7 @@ import java.util.function.Predicate; * * } */ -public interface SqlQuery extends Serializable { +public interface SqlQuery extends Serializable, CancelableQuery { /** * Execute the query returning a list. @@ -365,5 +365,10 @@ public interface SqlQuery extends Serializable { * Return the list of values. */ List findList(); + + /** + * Find streaming the result effectively consuming a row at a time. + */ + void findEach(Consumer consumer); } } diff --git a/ebean-api/src/main/java/io/ebean/Transaction.java b/ebean-api/src/main/java/io/ebean/Transaction.java index d4918e84e..0856a6e4e 100644 --- a/ebean-api/src/main/java/io/ebean/Transaction.java +++ b/ebean-api/src/main/java/io/ebean/Transaction.java @@ -59,6 +59,14 @@ public interface Transaction extends AutoCloseable { */ void register(TransactionCallback callback); + /** + * EXPERIMENTAL - turn on automatic persistence of dirty beans and batchMode true. + *

+ * With this turned on beans that are dirty in the persistence context + * are automatically persisted on flush() and commit(). + */ + void setAutoPersistUpdates(boolean autoPersistUpdates); + /** * Set a label on the transaction. *

@@ -339,15 +347,12 @@ public interface Transaction extends AutoCloseable { * The batch is automatically flushed when it hits the batch size and also when we * execute queries or when we mix UpdateSql and CallableSql with save and delete of * beans. - *

*

* We use {@link #flush()} to explicitly flush the batch and we can use * {@link #setFlushOnQuery(boolean)} and {@link #setFlushOnMixed(boolean)} * to control the automatic flushing behaviour. - *

*

* Example: batch processing of CallableSql executing every 10 rows - *

* *
{@code
    *
@@ -392,14 +397,11 @@ public interface Transaction extends AutoCloseable {
    * 

* This only takes effect when batch mode on the transaction has not already meant that * JDBC batch mode is being used. - *

*

* This is useful when the single save() or delete() cascades. For example, inserting a 'master' cascades * and inserts a collection of 'detail' beans. The detail beans can be inserted using JDBC batch. - *

*

* This is effectively already turned on for all platforms apart from older Sql Server. - *

* * @param batchMode the batch mode to use per save(), insert(), update() or delete() * @see io.ebean.config.DatabaseConfig#setPersistBatchOnCascade(PersistBatch) @@ -422,15 +424,19 @@ public interface Transaction extends AutoCloseable { int getBatchSize(); /** - * Specify if you want batched inserts to use getGeneratedKeys. + * Specify if we want batched inserts to use getGeneratedKeys. *

* By default batched inserts will try to use getGeneratedKeys if it is * supported by the underlying jdbc driver and database. - *

*

- * You may want to turn getGeneratedKeys off when you are inserting a large - * number of objects and you don't care about getting back the ids. - *

+ * We want to turn off getGeneratedKeys when we are inserting a large + * number of objects and we don't care about getting back the ids. In this + * way we avoid the extra cost of getting back the generated id values + * from the database. + *

+ * Note that when we do turn off getGeneratedKeys then we have the limitation + * that after a bean has been inserted we are unable to then mutate the bean + * and update it in the same transaction as we have not obtained it's id value. */ void setGetGeneratedKeys(boolean getGeneratedKeys); @@ -449,13 +455,11 @@ public interface Transaction extends AutoCloseable { *

* If you want to execute both WITHOUT having the batch automatically flush * you need to call this with batchFlushOnMixed = false. - *

*

* Note that UpdateSql and CallableSql are ALWAYS executed first (before the * beans are executed). This is because the UpdateSql and CallableSql have * already been bound to their PreparedStatements. The beans on the other hand * have a 2 step process (delayed binding). - *

*/ void setFlushOnMixed(boolean batchFlushOnMixed); @@ -473,7 +477,6 @@ public interface Transaction extends AutoCloseable { *

* Calling this method with batchFlushOnQuery = false means that you can * execute a query and the batch will not be automatically flushed. - *

*/ void setFlushOnQuery(boolean batchFlushOnQuery); @@ -490,7 +493,6 @@ public interface Transaction extends AutoCloseable { * should be flushed prior to executing a query. *

* The default is for this to be true. - *

*/ boolean isFlushOnQuery(); @@ -507,7 +509,6 @@ public interface Transaction extends AutoCloseable { * flush the batch if you like. *

* Flushing occurs automatically when: - *

*