From 1f928e65a46ff907f57272739be0f3ece464db81 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Tue, 30 Oct 2018 13:39:54 +1300 Subject: [PATCH] #1521 - Add API for using explicit transaction for UpdateQuery - e.g. ebeanServer.update(Customer.class)...update(activeTransaction); --- src/main/java/io/ebean/ExpressionList.java | 20 ++++++ src/main/java/io/ebean/Query.java | 20 ++++++ .../expression/DefaultExpressionList.java | 11 ++++ .../server/expression/JunctionExpression.java | 11 ++++ .../server/querydefn/DefaultOrmQuery.java | 11 ++++ src/test/java/io/ebean/UpdateQueryTest.java | 61 +++++++++++++++++++ 6 files changed, 134 insertions(+) diff --git a/src/main/java/io/ebean/ExpressionList.java b/src/main/java/io/ebean/ExpressionList.java index 9ce5e8d08..b156afdd9 100644 --- a/src/main/java/io/ebean/ExpressionList.java +++ b/src/main/java/io/ebean/ExpressionList.java @@ -166,6 +166,18 @@ public interface ExpressionList { */ int delete(); + /** + * 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. + *

+ * + * @return the number of rows that were deleted. + */ + int delete(Transaction transaction); + /** * Execute as a update query. * @@ -174,6 +186,14 @@ public interface ExpressionList { */ int update(); + /** + * Execute as a update query with the given transaction. + * + * @return the number of rows that were updated. + * @see UpdateQuery + */ + int update(Transaction transaction); + /** * Execute the query iterating over the results. * diff --git a/src/main/java/io/ebean/Query.java b/src/main/java/io/ebean/Query.java index 8749a2213..d2678e54e 100644 --- a/src/main/java/io/ebean/Query.java +++ b/src/main/java/io/ebean/Query.java @@ -924,11 +924,31 @@ public interface Query { */ int delete(); + /** + * Execute as a delete query returning the number of rows deleted using the given transaction. + *

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

+ * + * @return the number of beans/rows that were deleted. + */ + int delete(Transaction transaction); + /** * Execute the UpdateQuery returning the number of rows updated. + * + * @return the number of beans/rows updated. */ int update(); + /** + * Execute the UpdateQuery returning the number of rows updated using the given transaction. + * + * @return the number of beans/rows updated. + */ + int update(Transaction transaction); + /** * Return the count of entities this query should return. *

diff --git a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index 578e2d9b1..76211069b 100644 --- a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -17,6 +17,7 @@ import io.ebean.PagedList; import io.ebean.Pairs; import io.ebean.Query; import io.ebean.QueryIterator; +import io.ebean.Transaction; import io.ebean.Version; import io.ebean.event.BeanQueryRequest; import io.ebean.search.Match; @@ -356,11 +357,21 @@ public class DefaultExpressionList implements SpiExpressionList { return query.delete(); } + @Override + public int delete(Transaction transaction) { + return query.delete(transaction); + } + @Override public int update() { return query.update(); } + @Override + public int update(Transaction transaction) { + return query.update(transaction); + } + @Override public FutureIds findFutureIds() { return query.findFutureIds(); diff --git a/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 04bdc0777..4dc93e626 100644 --- a/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -16,6 +16,7 @@ import io.ebean.PagedList; import io.ebean.Pairs; import io.ebean.Query; import io.ebean.QueryIterator; +import io.ebean.Transaction; import io.ebean.Version; import io.ebean.event.BeanQueryRequest; import io.ebean.search.Match; @@ -318,11 +319,21 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression return exprList.delete(); } + @Override + public int delete(Transaction transaction) { + return exprList.delete(transaction); + } + @Override public int update() { return exprList.update(); } + @Override + public int update(Transaction transaction) { + return exprList.update(transaction); + } + @Override public Query asOf(Timestamp asOf) { return exprList.asOf(asOf); diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index e64ab5c79..33710a1d9 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -21,6 +21,7 @@ import io.ebean.Query; import io.ebean.QueryIterator; import io.ebean.QueryType; import io.ebean.RawSql; +import io.ebean.Transaction; import io.ebean.Version; import io.ebean.bean.CallStack; import io.ebean.bean.ObjectGraphNode; @@ -1384,11 +1385,21 @@ public class DefaultOrmQuery implements SpiQuery { return server.delete(this, null); } + @Override + public int delete(Transaction transaction) { + return server.delete(this, transaction); + } + @Override public int update() { return server.update(this, null); } + @Override + public int update(Transaction transaction) { + return server.update(this, transaction); + } + @Override public List findIds() { // a copy of this query is made in the server diff --git a/src/test/java/io/ebean/UpdateQueryTest.java b/src/test/java/io/ebean/UpdateQueryTest.java index 31285feb5..304a228f5 100644 --- a/src/test/java/io/ebean/UpdateQueryTest.java +++ b/src/test/java/io/ebean/UpdateQueryTest.java @@ -215,6 +215,67 @@ public class UpdateQueryTest extends BaseTestCase { assertThat(rows).isEqualTo(0); } + @Test + public void updateQuery_withExplicitTransaction() { + + EbeanServer server = server(); + + int rowsExprList; + int rowsQuery; + + try (Transaction transaction = server.beginTransaction()) { + + rowsExprList = server + .update(Customer.class) + .setRaw("status = coalesce(status, ?)", Customer.Status.ACTIVE) + .where() + .gt("id", 10000) + .update(transaction); + + rowsQuery = server + .update(Customer.class) + .setRaw("status = coalesce(status, ?)", Customer.Status.ACTIVE) + .where() + .gt("id", 10001) + .query().update(transaction); + + transaction.commit(); + } + + assertThat(rowsExprList).isEqualTo(0); + assertThat(rowsQuery).isEqualTo(0); + } + + + @Test + public void deleteQuery_withExplicitTransaction() { + + EbeanServer server = server(); + + int rowsExprList; + int rowsQuery; + + try (Transaction transaction = server.beginTransaction()) { + + rowsExprList = server + .update(Customer.class) + .where() + .gt("id", 10000) + .delete(transaction); + + rowsQuery = server + .update(Customer.class) + .where() + .gt("id", 10001) + .query().delete(transaction); + + transaction.commit(); + } + + assertThat(rowsExprList).isEqualTo(0); + assertThat(rowsQuery).isEqualTo(0); + } + @Test public void useViaEbean() {