You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2020/06/05 15:27:40 UTC
[ignite] branch master updated: IGNITE-13105 Fixed cursors leak in
RunningQueryManager. Code cleanup. #7888 - Fixes #7888.
This is an automated email from the ASF dual-hosted git repository.
akuznetsov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new f151563 IGNITE-13105 Fixed cursors leak in RunningQueryManager. Code cleanup. #7888 - Fixes #7888.
f151563 is described below
commit f15156375da16bd960bcf0c36c96bf8f26398ba7
Author: Alexey Kuznetsov <ak...@apache.org>
AuthorDate: Fri Jun 5 22:27:14 2020 +0700
IGNITE-13105 Fixed cursors leak in RunningQueryManager. Code cleanup. #7888 - Fixes #7888.
Signed-off-by: Alexey Kuznetsov <ak...@apache.org>
---
.../repository/query/IgniteRepositoryQuery.java | 52 ++++++++++------
.../springdata/IgniteSpringDataCrudSelfTest.java | 33 ++++++++++
.../repository/query/IgniteRepositoryQuery.java | 52 ++++++++++------
.../springdata/IgniteSpringDataCrudSelfTest.java | 33 ++++++++++
.../repository/query/IgniteRepositoryQuery.java | 72 +++++++++++++---------
.../springdata/IgniteSpringDataCrudSelfTest.java | 33 ++++++++++
.../ignite/springdata/misc/PersonRepository.java | 3 +
7 files changed, 212 insertions(+), 66 deletions(-)
diff --git a/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
index 3bae2cc..e445e78 100644
--- a/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
+++ b/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
@@ -20,10 +20,10 @@ package org.apache.ignite.springdata20.repository.query;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import javax.cache.Cache;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.Query;
@@ -42,10 +42,13 @@ import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
+import static org.apache.ignite.springdata20.repository.query.IgniteQueryGenerator.addPaging;
+import static org.apache.ignite.springdata20.repository.query.IgniteQueryGenerator.addSorting;
+
/**
* Ignite SQL query implementation.
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings({"unchecked", "rawtypes"})
public class IgniteRepositoryQuery implements RepositoryQuery {
/** Defines the way how to process query result */
private enum ReturnStrategy {
@@ -118,9 +121,9 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
@Override public Object execute(Object[] prmtrs) {
Query qry = prepareQuery(prmtrs);
- QueryCursor qryCursor = cache.query(qry);
-
- return transformQueryCursor(prmtrs, qryCursor);
+ try (QueryCursor qryCursor = cache.query(qry)) {
+ return transformQueryCursor(prmtrs, qryCursor);
+ }
}
/** {@inheritDoc} */
@@ -196,7 +199,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
* @return Query cursor or slice
*/
@Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
- if (this.qry.isFieldQuery()) {
+ if (qry.isFieldQuery()) {
Iterable<List> qryIter = (Iterable<List>)qryCursor;
switch (returnStgy) {
@@ -207,6 +210,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
list.add(entry.get(0));
return list;
+
case ONE_VALUE:
Iterator<List> iter = qryIter.iterator();
@@ -214,6 +218,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter.next().get(0);
return null;
+
case SLICE_OF_VALUES:
List content = new ArrayList<>();
@@ -221,10 +226,13 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
content.add(entry.get(0));
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_LISTS:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_LISTS:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -240,6 +248,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
list.add(entry.getValue());
return list;
+
case ONE_VALUE:
Iterator<CacheEntryImpl> iter1 = qryIter.iterator();
@@ -247,6 +256,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter1.next().getValue();
return null;
+
case CACHE_ENTRY:
Iterator<CacheEntryImpl> iter2 = qryIter.iterator();
@@ -254,6 +264,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter2.next();
return null;
+
case SLICE_OF_VALUES:
List content = new ArrayList<>();
@@ -261,10 +272,13 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
content.add(entry.getValue());
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_CACHE_ENTRIES:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_CACHE_ENTRIES:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -275,38 +289,38 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
* @param prmtrs Prmtrs.
* @return prepared query for execution
*/
+ @SuppressWarnings("deprecation")
@NotNull private Query prepareQuery(Object[] prmtrs) {
Object[] parameters = prmtrs;
String sql = qry.sql();
- Query query;
-
switch (qry.options()) {
case SORTING:
- sql = IgniteQueryGenerator.addSorting(new StringBuilder(sql),
- (Sort)parameters[parameters.length - 1]).toString();
+ sql = addSorting(new StringBuilder(sql), (Sort)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
case PAGINATION:
- sql = IgniteQueryGenerator.addPaging(new StringBuilder(sql),
- (Pageable)parameters[parameters.length - 1]).toString();
+ sql = addPaging(new StringBuilder(sql), (Pageable)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
+ case NONE:
+ // No-op.
}
if (qry.isFieldQuery()) {
SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
sqlFieldsQry.setArgs(parameters);
- query = sqlFieldsQry;
+ return sqlFieldsQry;
}
- else {
- SqlQuery sqlQry = new SqlQuery(type, sql);
- sqlQry.setArgs(parameters);
- query = sqlQry;
- }
+ SqlQuery sqlQry = new SqlQuery(type, sql);
+ sqlQry.setArgs(parameters);
- return query;
+ return sqlQry;
}
}
diff --git a/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
index b2dce2f..b4dcf23 100644
--- a/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -24,6 +24,9 @@ import java.util.List;
import java.util.Optional;
import java.util.TreeSet;
import javax.cache.CacheException;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.query.RunningQueryManager;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
import org.apache.ignite.springdata.misc.Person;
import org.apache.ignite.springdata.misc.PersonKey;
@@ -55,6 +58,9 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
@Rule
public final ExpectedException expected = ExpectedException.none();
+ /** */
+ private static IgniteEx ignite;
+
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
@@ -65,6 +71,7 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
repo = ctx.getBean(PersonRepository.class);
repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
+ ignite = ctx.getBean(IgniteEx.class);
}
/** {@inheritDoc} */
@@ -356,4 +363,30 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
return ids;
}
+
+ /** */
+ @Test
+ public void shouldNotLeakCursorsInRunningQueryManager() {
+ RunningQueryManager runningQryMgr = ((IgniteH2Indexing)ignite.context().query().getIndexing()).runningQueryManager();
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ List<Person> res = repo.simpleQuery("person0");
+
+ assertEquals(1, res.size());
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ Person person = repo.findTopBySecondNameStartingWith("lastName");
+
+ assertNotNull(person);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ long cnt = repo.countByFirstName("person0");
+
+ assertEquals(1, cnt);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ }
}
diff --git a/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
index 0d99c59..9f27a95 100644
--- a/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
+++ b/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
@@ -20,10 +20,10 @@ package org.apache.ignite.springdata22.repository.query;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import javax.cache.Cache;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.Query;
@@ -42,10 +42,13 @@ import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
+import static org.apache.ignite.springdata22.repository.query.IgniteQueryGenerator.addPaging;
+import static org.apache.ignite.springdata22.repository.query.IgniteQueryGenerator.addSorting;
+
/**
* Ignite SQL query implementation.
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings({"unchecked", "rawtypes"})
public class IgniteRepositoryQuery implements RepositoryQuery {
/** Defines the way how to process query result */
private enum ReturnStrategy {
@@ -118,9 +121,9 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
@Override public Object execute(Object[] prmtrs) {
Query qry = prepareQuery(prmtrs);
- QueryCursor qryCursor = cache.query(qry);
-
- return transformQueryCursor(prmtrs, qryCursor);
+ try (QueryCursor qryCursor = cache.query(qry)) {
+ return transformQueryCursor(prmtrs, qryCursor);
+ }
}
/** {@inheritDoc} */
@@ -196,7 +199,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
* @return Query cursor or slice
*/
@Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
- if (this.qry.isFieldQuery()) {
+ if (qry.isFieldQuery()) {
Iterable<List> qryIter = (Iterable<List>)qryCursor;
switch (returnStgy) {
@@ -207,6 +210,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
list.add(entry.get(0));
return list;
+
case ONE_VALUE:
Iterator<List> iter = qryIter.iterator();
@@ -214,6 +218,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter.next().get(0);
return null;
+
case SLICE_OF_VALUES:
List content = new ArrayList<>();
@@ -221,10 +226,13 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
content.add(entry.get(0));
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_LISTS:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_LISTS:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -240,6 +248,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
list.add(entry.getValue());
return list;
+
case ONE_VALUE:
Iterator<CacheEntryImpl> iter1 = qryIter.iterator();
@@ -247,6 +256,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter1.next().getValue();
return null;
+
case CACHE_ENTRY:
Iterator<CacheEntryImpl> iter2 = qryIter.iterator();
@@ -254,6 +264,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter2.next();
return null;
+
case SLICE_OF_VALUES:
List content = new ArrayList<>();
@@ -261,10 +272,13 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
content.add(entry.getValue());
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_CACHE_ENTRIES:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_CACHE_ENTRIES:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -275,38 +289,38 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
* @param prmtrs Prmtrs.
* @return prepared query for execution
*/
+ @SuppressWarnings("deprecation")
@NotNull private Query prepareQuery(Object[] prmtrs) {
Object[] parameters = prmtrs;
String sql = qry.sql();
- Query query;
-
switch (qry.options()) {
case SORTING:
- sql = IgniteQueryGenerator.addSorting(new StringBuilder(sql),
- (Sort)parameters[parameters.length - 1]).toString();
+ sql = addSorting(new StringBuilder(sql), (Sort)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
case PAGINATION:
- sql = IgniteQueryGenerator.addPaging(new StringBuilder(sql),
- (Pageable)parameters[parameters.length - 1]).toString();
+ sql = addPaging(new StringBuilder(sql), (Pageable)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
+ case NONE:
+ // No-op.
}
if (qry.isFieldQuery()) {
SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
sqlFieldsQry.setArgs(parameters);
- query = sqlFieldsQry;
+ return sqlFieldsQry;
}
- else {
- SqlQuery sqlQry = new SqlQuery(type, sql);
- sqlQry.setArgs(parameters);
- query = sqlQry;
- }
+ SqlQuery sqlQry = new SqlQuery(type, sql);
+ sqlQry.setArgs(parameters);
- return query;
+ return sqlQry;
}
}
diff --git a/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
index 19ee296..5d863e4 100644
--- a/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -24,6 +24,9 @@ import java.util.List;
import java.util.Optional;
import java.util.TreeSet;
import javax.cache.CacheException;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.query.RunningQueryManager;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
import org.apache.ignite.springdata.misc.Person;
import org.apache.ignite.springdata.misc.PersonKey;
@@ -55,6 +58,9 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
@Rule
public final ExpectedException expected = ExpectedException.none();
+ /** */
+ private static IgniteEx ignite;
+
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
@@ -65,6 +71,7 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
repo = ctx.getBean(PersonRepository.class);
repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
+ ignite = ctx.getBean(IgniteEx.class);
}
/** {@inheritDoc} */
@@ -356,4 +363,30 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
return ids;
}
+
+ /** */
+ @Test
+ public void shouldNotLeakCursorsInRunningQueryManager() {
+ RunningQueryManager runningQryMgr = ((IgniteH2Indexing)ignite.context().query().getIndexing()).runningQueryManager();
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ List<Person> res = repo.simpleQuery("person0");
+
+ assertEquals(1, res.size());
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ Person person = repo.findTopBySecondNameStartingWith("lastName");
+
+ assertNotNull(person);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ long cnt = repo.countByFirstName("person0");
+
+ assertEquals(1, cnt);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ }
}
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
index 7b0c98a..e351c61 100644
--- a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import javax.cache.Cache;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.Query;
@@ -41,10 +42,13 @@ import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
+import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addPaging;
+import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addSorting;
+
/**
* Ignite SQL query implementation.
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings({"unchecked", "rawtypes"})
public class IgniteRepositoryQuery implements RepositoryQuery {
/** Defines the way how to process query result */
private enum ReturnStrategy {
@@ -106,7 +110,6 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
type = metadata.getDomainType();
this.qry = qry;
this.cache = cache;
-
this.metadata = metadata;
this.mtd = mtd;
this.factory = factory;
@@ -118,9 +121,9 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
@Override public Object execute(Object[] prmtrs) {
Query qry = prepareQuery(prmtrs);
- QueryCursor qryCursor = cache.query(qry);
-
- return transformQueryCursor(prmtrs, qryCursor);
+ try (QueryCursor qryCursor = cache.query(qry)) {
+ return transformQueryCursor(prmtrs, qryCursor);
+ }
}
/** {@inheritDoc} */
@@ -131,6 +134,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
/**
* @param mtd Method.
* @param isFieldQry Is field query.
+ * @return Return strategy type.
*/
private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
Class<?> returnType = mtd.getReturnType();
@@ -164,6 +168,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
/**
* @param cls Class 1.
* @param mtd Method.
+ * @return if {@code mtd} return type is assignable from {@code cls}
*/
private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
Type[] actualTypeArguments = ((ParameterizedType)mtd.getGenericReturnType()).getActualTypeArguments();
@@ -191,37 +196,43 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
/**
* @param prmtrs Prmtrs.
* @param qryCursor Query cursor.
+ * @return Query cursor or slice
*/
@Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
- if (this.qry.isFieldQuery()) {
- Iterable<ArrayList> qryIter = (Iterable<ArrayList>)qryCursor;
+ if (qry.isFieldQuery()) {
+ Iterable<List> qryIter = (Iterable<List>)qryCursor;
switch (returnStgy) {
case LIST_OF_VALUES:
- ArrayList list = new ArrayList();
+ List list = new ArrayList<>();
- for (ArrayList entry : qryIter)
+ for (List entry : qryIter)
list.add(entry.get(0));
return list;
+
case ONE_VALUE:
- Iterator<ArrayList> iter = qryIter.iterator();
+ Iterator<List> iter = qryIter.iterator();
if (iter.hasNext())
return iter.next().get(0);
return null;
+
case SLICE_OF_VALUES:
- ArrayList content = new ArrayList();
+ List content = new ArrayList<>();
- for (ArrayList entry : qryIter)
+ for (List entry : qryIter)
content.add(entry.get(0));
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_LISTS:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_LISTS:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -231,12 +242,13 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
switch (returnStgy) {
case LIST_OF_VALUES:
- ArrayList list = new ArrayList();
+ List list = new ArrayList<>();
for (CacheEntryImpl entry : qryIter)
list.add(entry.getValue());
return list;
+
case ONE_VALUE:
Iterator<CacheEntryImpl> iter1 = qryIter.iterator();
@@ -244,6 +256,7 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter1.next().getValue();
return null;
+
case CACHE_ENTRY:
Iterator<CacheEntryImpl> iter2 = qryIter.iterator();
@@ -251,17 +264,21 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
return iter2.next();
return null;
+
case SLICE_OF_VALUES:
- ArrayList content = new ArrayList();
+ List content = new ArrayList<>();
for (CacheEntryImpl entry : qryIter)
content.add(entry.getValue());
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
+
case SLICE_OF_CACHE_ENTRIES:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
+
case LIST_OF_CACHE_ENTRIES:
return qryCursor.getAll();
+
default:
throw new IllegalStateException();
}
@@ -272,39 +289,38 @@ public class IgniteRepositoryQuery implements RepositoryQuery {
* @param prmtrs Prmtrs.
* @return prepared query for execution
*/
+ @SuppressWarnings("deprecation")
@NotNull private Query prepareQuery(Object[] prmtrs) {
Object[] parameters = prmtrs;
String sql = qry.sql();
- Query query;
-
switch (qry.options()) {
case SORTING:
- sql = IgniteQueryGenerator.addSorting(new StringBuilder(sql),
- (Sort)parameters[parameters.length - 1]).toString();
+ sql = addSorting(new StringBuilder(sql), (Sort)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
case PAGINATION:
- sql = IgniteQueryGenerator.addPaging(new StringBuilder(sql),
- (Pageable)parameters[parameters.length - 1]).toString();
+ sql = addPaging(new StringBuilder(sql), (Pageable)parameters[parameters.length - 1]).toString();
parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+
break;
+
+ case NONE:
+ // No-op.
}
if (qry.isFieldQuery()) {
SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
sqlFieldsQry.setArgs(parameters);
- query = sqlFieldsQry;
+ return sqlFieldsQry;
}
- else {
- SqlQuery sqlQry = new SqlQuery(type, sql);
- sqlQry.setArgs(parameters);
- query = sqlQry;
- }
+ SqlQuery sqlQry = new SqlQuery(type, sql);
+ sqlQry.setArgs(parameters);
- return query;
+ return sqlQry;
}
}
-
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
index c055c90..65f9239 100644
--- a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -22,6 +22,9 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeSet;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.query.RunningQueryManager;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
import org.apache.ignite.springdata.misc.Person;
import org.apache.ignite.springdata.misc.PersonKey;
@@ -53,6 +56,9 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
@Rule
public final ExpectedException expected = ExpectedException.none();
+ /** */
+ private static IgniteEx ignite;
+
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
@@ -63,6 +69,7 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
repo = ctx.getBean(PersonRepository.class);
repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
+ ignite = ctx.getBean(IgniteEx.class);
}
/** {@inheritDoc} */
@@ -254,4 +261,30 @@ public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
return ids;
}
+
+ /** */
+ @Test
+ public void shouldNotLeakCursorsInRunningQueryManager() {
+ RunningQueryManager runningQryMgr = ((IgniteH2Indexing)ignite.context().query().getIndexing()).runningQueryManager();
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ List<Person> res = repo.simpleQuery("person0");
+
+ assertEquals(1, res.size());
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ Person person = repo.findTopBySecondNameStartingWith("lastName");
+
+ assertNotNull(person);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+
+ long cnt = repo.countByFirstName("person0");
+
+ assertEquals(1, cnt);
+
+ assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ }
}
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
index db6ace7..d8444d1 100644
--- a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
@@ -48,6 +48,9 @@ public interface PersonRepository extends IgniteRepository<Person, Integer> {
public Iterable<Person> findFirst10ByFirstNameLike(String val);
/** */
+ public int countByFirstName(String val);
+
+ /** */
public int countByFirstNameLike(String val);
/** */