#717 - Remove findIterate() ... migrate to findEach() or findEachWhile()

This commit is contained in:
Robin Bygrave
2016-05-20 22:38:07 +12:00
parent 11d623cb69
commit 662be92a16
20 changed files with 99 additions and 210 deletions
@@ -696,24 +696,6 @@ public interface EbeanServer {
*/
<T> List<Object> findIds(Query<T> query, Transaction transaction);
/**
* Return a QueryIterator for the query.
* <p>
* Generally using {@link #findEach(Query, QueryEachConsumer, Transaction)} or
* {@link #findEachWhile(Query, QueryEachWhileConsumer, 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#findEach(QueryEachConsumer)
* @see Query#findEachWhile(QueryEachWhileConsumer)
*/
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Execute the query visiting the each bean one at a time.
* <p>
@@ -139,13 +139,6 @@ public interface ExpressionList<T> {
*/
int delete();
/**
* Execute the query iterating over the results.
*
* @see Query#findIterate()
*/
QueryIterator<T> findIterate();
/**
* Execute the query process the beans one at a time.
*
-19
View File
@@ -547,25 +547,6 @@ public interface Query<T> {
*/
List<Object> findIds();
/**
* Execute the query iterating over the results.
* <p>
* Remember that with {@link QueryIterator} you must call
* {@link QueryIterator#close()} when you have finished iterating the results
* (typically in a finally block).
* </p>
* <p>
* findEach() and findEachWhile() are preferred to findIterate() as they ensure
* the jdbc statement and resultSet are closed at the end of the iteration.
* </p>
* <p>
* This query will execute against the EbeanServer that was used to create it.
* </p>
*/
QueryIterator<T> findIterate();
/**
* Execute the query processing the beans one at a time.
* <p>
@@ -1249,7 +1249,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
request.initTransIfRequired();
request.findEach(consumer);
// no try finally - findVisit guarantee's cleanup of the transaction if required
// no try finally - findEach guarantee's cleanup of the transaction if required
}
public <T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction t) {
@@ -1262,21 +1262,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
request.initTransIfRequired();
request.findEachWhile(consumer);
// no try finally - findVisit guarantee's cleanup of the transaction if required
}
public <T> QueryIterator<T> findIterate(Query<T> query, Transaction t) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, t);
try {
request.initTransIfRequired();
return request.findIterate();
} catch (RuntimeException ex) {
request.endTransIfRequired();
throw ex;
}
// no try finally - findEachWhile guarantee's cleanup of the transaction if required
}
@Override
@@ -1,6 +1,5 @@
package com.avaje.ebeaninternal.server.core;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebeaninternal.api.BeanIdList;
@@ -3,7 +3,6 @@ package com.avaje.ebeaninternal.server.core;
import com.avaje.ebean.PersistenceContextScope;
import com.avaje.ebean.QueryEachConsumer;
import com.avaje.ebean.QueryEachWhileConsumer;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.RawSql;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
@@ -1,4 +1,4 @@
package com.avaje.ebean;
package com.avaje.ebeaninternal.server.core;
import java.util.Iterator;
@@ -2,7 +2,6 @@ package com.avaje.ebeaninternal.server.core;
import com.avaje.ebean.QueryEachConsumer;
import com.avaje.ebean.QueryEachWhileConsumer;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebeaninternal.api.SpiQuery;
@@ -322,11 +322,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
query.findEachWhile(consumer);
}
@Override
public QueryIterator<T> findIterate() {
return query.findIterate();
}
@Override
public List<T> findList() {
return query.findList();
@@ -12,7 +12,6 @@ import com.avaje.ebean.PagedList;
import com.avaje.ebean.Query;
import com.avaje.ebean.QueryEachConsumer;
import com.avaje.ebean.QueryEachWhileConsumer;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.Version;
import com.avaje.ebean.event.BeanQueryRequest;
import com.avaje.ebean.search.Match;
@@ -345,11 +344,6 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
exprList.findEachWhile(consumer);
}
@Override
public QueryIterator<T> findIterate() {
return exprList.findIterate();
}
@Override
public List<T> findList() {
return exprList.findList();
@@ -1,6 +1,6 @@
package com.avaje.ebeaninternal.server.query;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebeaninternal.server.core.QueryIterator;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
@@ -1,6 +1,6 @@
package com.avaje.ebeaninternal.server.query;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebeaninternal.server.core.QueryIterator;
import com.avaje.ebean.ValuePair;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
@@ -4,7 +4,7 @@ import java.sql.SQLException;
import javax.persistence.PersistenceException;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebeaninternal.server.core.QueryIterator;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
/**
@@ -5,7 +5,7 @@ import java.util.ArrayList;
import javax.persistence.PersistenceException;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebeaninternal.server.core.QueryIterator;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
/**
@@ -1,6 +1,6 @@
package com.avaje.ebeaninternal.server.query;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebeaninternal.server.core.QueryIterator;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
@@ -1084,11 +1084,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return server.findVersions(this, null);
}
@Override
public QueryIterator<T> findIterate() {
return server.findIterate(this, null);
}
@Override
public List<T> findList() {
return server.findList(this, null);
@@ -445,11 +445,6 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public <T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction) {
return null;
}
@Override
public <T> void findEach(Query<T> query, QueryEachConsumer<T> consumer, Transaction transaction) {
@@ -3,12 +3,14 @@ package com.avaje.tests.query;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.QueryEachConsumer;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
public class TestOneToManyCorrectGrouping extends BaseTestCase {
@@ -24,21 +26,17 @@ public class TestOneToManyCorrectGrouping extends BaseTestCase {
.where().le("id", 2)
.query();
QueryIterator<Customer> customerQueryIterator = customerQuery.findIterate();
final AtomicInteger count = new AtomicInteger();
try {
int count = 0;
while (customerQueryIterator.hasNext()) {
Customer customer = customerQueryIterator.next();
customerQuery.findEach(new QueryEachConsumer<Customer>() {
@Override
public void accept(Customer customer) {
for (Order order : customer.getOrders()) {
order.getId();
}
count++;
count.incrementAndGet();
}
assertEquals(EXPECTED_ITERATIONS, count);
} finally {
customerQueryIterator.close();
}
});
assertEquals(EXPECTED_ITERATIONS, count.get());
}
}
@@ -12,6 +12,7 @@ import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.ResetBasicData;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
@@ -31,20 +32,16 @@ public class TestQueryFindIterate extends BaseTestCase {
//.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
int count = 0;
final AtomicInteger count = new AtomicInteger();
QueryIterator<Customer> it = query.findIterate();
try {
while (it.hasNext()) {
Customer customer = it.next();
customer.hashCode();
count++;
query.findEach(new QueryEachConsumer<Customer>() {
@Override
public void accept(Customer bean) {
count.incrementAndGet();
}
} finally {
it.close();
}
});
assertEquals(2, count);
assertEquals(2, count.get());
}
@Test
@@ -52,25 +49,20 @@ public class TestQueryFindIterate extends BaseTestCase {
ResetBasicData.reset();
QueryIterator<Order> queryIterator = Ebean.find(Order.class)
Ebean.find(Order.class)
//.select("orderDate")
.where().gt("id",0).le("id",10)
.findIterate();
try {
while (queryIterator.hasNext()) {
Order order = queryIterator.next();
Customer customer = order.getCustomer();
// invoke lazy loading on customer, order details and order shipments
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
} finally {
queryIterator.close();
}
.findEach(new QueryEachConsumer<Order>() {
@Override
public void accept(Order order) {
Customer customer = order.getCustomer();
// invoke lazy loading on customer, order details and order shipments
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
});
}
@@ -81,26 +73,22 @@ public class TestQueryFindIterate extends BaseTestCase {
LoggedSqlCollector.start();
QueryIterator<Order> queryIterator = Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.select("status, orderDate")
.fetch("customer", "name")
.where().gt("id",0).le("id",10)
.setUseCache(false)
.findIterate();
Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.select("status, orderDate")
.fetch("customer", "name")
.where().gt("id",0).le("id",10)
.setUseCache(false)
.findEach(new QueryEachConsumer<Order>() {
@Override
public void accept(Order order) {
Customer customer = order.getCustomer();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
});
try {
while (queryIterator.hasNext()) {
Order order = queryIterator.next();
Customer customer = order.getCustomer();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
} finally {
queryIterator.close();
}
List<String> loggedSql = LoggedSqlCollector.stop();
@@ -123,29 +111,24 @@ public class TestQueryFindIterate extends BaseTestCase {
Ebean.getServerCacheManager().getBeanCache(OrderShipment.class).clear();
Ebean.getServerCacheManager().getQueryCache(OrderShipment.class).clear();
QueryIterator<Order> queryIterator = Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.setUseCache(false)
.select("status, orderDate")
.fetch("customer", "name")
.fetch("details")
.where().gt("id",0).le("id",10)
.order().asc("id")
.findIterate();
try {
while (queryIterator.hasNext()) {
Order order = queryIterator.next();
Customer customer = order.getCustomer();
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
} finally {
queryIterator.close();
}
Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.setUseCache(false)
.select("status, orderDate")
.fetch("customer", "name")
.fetch("details")
.where().gt("id",0).le("id",10)
.order().asc("id")
.findEach(new QueryEachConsumer<Order>() {
@Override
public void accept(Order order) {
Customer customer = order.getCustomer();
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
}
});
List<String> loggedSql = LoggedSqlCollector.stop();
@@ -168,8 +151,12 @@ public class TestQueryFindIterate extends BaseTestCase {
.setMaxRows(2);
// this throws an exception immediately
QueryIterator<Customer> it = query.findIterate();
it.close();
query.findEach(new QueryEachConsumer<Customer>() {
@Override
public void accept(Customer bean) {
}
});
if (!server.getName().equals("h2")) {
// MySql allows the query with type conversion?
@@ -191,17 +178,13 @@ public class TestQueryFindIterate extends BaseTestCase {
.where().gt("id", 0)
.setMaxRows(2);
QueryIterator<Customer> it = query.findIterate();
try {
while (it.hasNext()) {
Customer customer = it.next();
query.findEach(new QueryEachConsumer<Customer>() {
@Override
public void accept(Customer customer) {
if (customer != null) {
throw new IllegalStateException("cause an exception");
}
}
} finally {
it.close();
}
});
}
}
@@ -11,7 +11,6 @@ import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.Transaction;
import com.avaje.tests.model.basic.EBasic;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -52,33 +51,24 @@ public class TestFindIterateHeapDump extends BaseTestCase {
transaction.end();
}
QueryIterator<EBasic> iterate = server.find(EBasic.class).findIterate();
iterate.hashCode();
try {
// Intentionally not iterating through the iterator to
// try {
// while (iterate.hasNext()) {
// EBasic eBasic = iterate.next();
// eBasic.getDescription();
// }
// } finally {
// iterate.close();
// }
String fileName = "heap-dump6.snapshot";
File file = new File(fileName);
if (file.exists())
file.delete();
dumpHeap(fileName, true);
} finally {
iterate.close();
}
// Intentionally not iterating through the iterator to
// try {
// while (iterate.hasNext()) {
// EBasic eBasic = iterate.next();
// eBasic.getDescription();
// }
// } finally {
// iterate.close();
// }
String fileName = "heap-dump6.snapshot";
File file = new File(fileName);
if (file.exists())
file.delete();
dumpHeap(fileName, true);
}
static void dumpHeap(String fileName, boolean live) {