diff --git a/src/main/java/org/springframework/data/gemfire/repository/query/GemfireQueryCreator.java b/src/main/java/org/springframework/data/gemfire/repository/query/GemfireQueryCreator.java index 0d28e039..9de897b2 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/query/GemfireQueryCreator.java +++ b/src/main/java/org/springframework/data/gemfire/repository/query/GemfireQueryCreator.java @@ -44,10 +44,9 @@ class GemfireQueryCreator extends AbstractQueryCreator * @param entity must not be {@literal null}. */ public GemfireQueryCreator(PartTree tree, GemfirePersistentEntity entity) { - super(tree); - this.query = new QueryBuilder(entity); + this.query = new QueryBuilder(entity, tree); this.indexes = new IndexProvider(); } @@ -57,7 +56,6 @@ class GemfireQueryCreator extends AbstractQueryCreator */ @Override public QueryString createQuery(Sort dynamicSort) { - this.indexes = new IndexProvider(); return super.createQuery(dynamicSort); } @@ -95,11 +93,10 @@ class GemfireQueryCreator extends AbstractQueryCreator */ @Override protected QueryString complete(Predicates criteria, Sort sort) { - - QueryString result = query.create(criteria); + QueryString result = query.create(criteria).orderBy(sort); if (LOG.isDebugEnabled()) { - LOG.debug("Created query: " + result.toString()); + LOG.debug(String.format("Created Query '%1$s'", result.toString())); } return result; @@ -119,6 +116,7 @@ class GemfireQueryCreator extends AbstractQueryCreator */ @Override public boolean hasNext() { + // TODO really? return index <= Integer.MAX_VALUE; } @@ -140,4 +138,5 @@ class GemfireQueryCreator extends AbstractQueryCreator throw new UnsupportedOperationException(); } } + } diff --git a/src/main/java/org/springframework/data/gemfire/repository/query/PartTreeGemfireRepositoryQuery.java b/src/main/java/org/springframework/data/gemfire/repository/query/PartTreeGemfireRepositoryQuery.java index 13f77d86..9051838f 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/query/PartTreeGemfireRepositoryQuery.java +++ b/src/main/java/org/springframework/data/gemfire/repository/query/PartTreeGemfireRepositoryQuery.java @@ -15,13 +15,15 @@ */ package org.springframework.data.gemfire.repository.query; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import org.springframework.data.domain.Sort; import org.springframework.data.gemfire.GemfireTemplate; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.data.repository.query.parser.PartTree; /** @@ -71,35 +73,31 @@ public class PartTreeGemfireRepositoryQuery extends GemfireRepositoryQuery { } private Object[] prepareStringParameters(Object[] parameters) { + Iterator partsIterator = tree.getParts().iterator(); + List stringParameters = new ArrayList(parameters.length); - Iterator iterator = tree.getParts().iterator(); - Object[] result = new Object[parameters.length]; - - for (int i = 0; i < parameters.length; i++) { - Object parameter = parameters[i]; - - if (parameter == null) { - result[i] = parameter; - continue; + for (Object parameter : parameters) { + if (parameter == null || parameter instanceof Sort) { + stringParameters.add(parameter); } - - Type type = iterator.next().getType(); - - switch (type) { - case CONTAINING: - result[i] = String.format("%%%s%%", parameter.toString()); - break; - case STARTING_WITH: - result[i] = String.format("%s%%", parameter.toString()); - break; - case ENDING_WITH: - result[i] = String.format("%%%s", parameter.toString()); - break; - default: - result[i] = parameter; + else { + switch (partsIterator.next().getType()) { + case CONTAINING: + stringParameters.add(String.format("%%%s%%", parameter.toString())); + break; + case STARTING_WITH: + stringParameters.add(String.format("%s%%", parameter.toString())); + break; + case ENDING_WITH: + stringParameters.add(String.format("%%%s", parameter.toString())); + break; + default: + stringParameters.add(parameter); + } } } - return result; + return stringParameters.toArray(); } + } diff --git a/src/main/java/org/springframework/data/gemfire/repository/query/QueryBuilder.java b/src/main/java/org/springframework/data/gemfire/repository/query/QueryBuilder.java index 7d1e2b8c..b7a70e98 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/query/QueryBuilder.java +++ b/src/main/java/org/springframework/data/gemfire/repository/query/QueryBuilder.java @@ -20,9 +20,12 @@ import org.springframework.data.repository.query.parser.PartTree; import org.springframework.util.Assert; /** - * + * The QueryBuilder class is used to build a QueryString. + * * @author Oliver Gierke * @author David Turanski + * @author John Blum + * @see org.springframework.data.gemfire.repository.query.QueryString */ class QueryBuilder { @@ -31,17 +34,18 @@ class QueryBuilder { private final String query; public QueryBuilder(String source) { - Assert.hasText(source); + Assert.hasText(source, "The OQL Query string must be specified."); this.query = source; } - public QueryBuilder(GemfirePersistentEntity entity) { - this(String.format("SELECT * FROM /%s %s", entity.getRegionName(), DEFAULT_ALIAS)); + public QueryBuilder(GemfirePersistentEntity entity, PartTree tree) { + this(String.format(tree.isDistinct() ? "SELECT DISTINCT * FROM /%1$s %2$s" : "SELECT * FROM /%1$s %2$s", + entity.getRegionName(), DEFAULT_ALIAS)); } public QueryString create(Predicate predicate) { - - return new QueryString(query + " WHERE " + predicate.toString(DEFAULT_ALIAS)); + return new QueryString(predicate != null ? String.format("%1$s WHERE %2$s", query, + predicate.toString(DEFAULT_ALIAS)) : query); } /* @@ -52,4 +56,5 @@ class QueryBuilder { public String toString() { return query; } + } diff --git a/src/main/java/org/springframework/data/gemfire/repository/query/QueryString.java b/src/main/java/org/springframework/data/gemfire/repository/query/QueryString.java index 80fc5ac4..67080ae8 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/query/QueryString.java +++ b/src/main/java/org/springframework/data/gemfire/repository/query/QueryString.java @@ -21,11 +21,12 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.gemstone.gemfire.cache.Region; - +import org.springframework.data.domain.Sort; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import com.gemstone.gemfire.cache.Region; + /** * Value object to work with OQL query strings. * @@ -33,7 +34,7 @@ import org.springframework.util.StringUtils; * @author David Turanski * @author John Blum */ -class QueryString { +public class QueryString { private static final String IN_PATTERN = "(?<=IN (SET|LIST) )\\$\\d"; private static final String IN_PARAMETER_PATTERN = "(?<=IN (SET|LIST) \\$)\\d"; @@ -44,7 +45,7 @@ class QueryString { /** * Creates a {@link QueryString} from the given {@link String} query. * - * @param source + * @param source a String containing the OQL Query. */ public QueryString(String source) { Assert.hasText(source, "The OQL statement (Query) to execute must be specified!"); @@ -56,8 +57,8 @@ class QueryString { * * @param domainClass must not be {@literal null}. */ - @SuppressWarnings("unused") - public QueryString(Class domainClass) { + @SuppressWarnings("unused") + public QueryString(Class domainClass) { this(domainClass, false); } @@ -68,41 +69,45 @@ class QueryString { * @param isCountQuery indicates if this is a count query */ public QueryString(Class domainClass, boolean isCountQuery) { - this(String.format(isCountQuery ? "SELECT count(*) FROM /%s" : "SELECT * FROM /%s", domainClass.getSimpleName())); - } - - /** - * Replaces the domain classes referenced inside the current query with the given {@link Region}. - * - * @param domainClass must not be {@literal null}. - * @param region must not be {@literal null}. - * @return - */ - @SuppressWarnings("unused") - public QueryString forRegion(Class domainClass, Region region) { - return new QueryString(query.replaceAll(REGION_PATTERN, region.getFullPath())); + this(String.format(isCountQuery ? "SELECT count(*) FROM /%s" : "SELECT * FROM /%s", + domainClass.getSimpleName())); } /** * Binds the given values to the {@literal IN} parameter keyword by expanding the given values into a comma-separated * {@link String}. - * + * * @param values the values to bind, returns the {@link QueryString} as is if {@literal null} is given. - * @return + * @return a Query String having "in" parameters bound with values. */ - public QueryString bindIn(Collection values) { - if (values != null) { - String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'"); - return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString))); - } + public QueryString bindIn(Collection values) { + if (values != null) { + String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'"); + return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString))); + } - return this; - } + return this; + } + + /** + * Replaces the domain classes referenced inside the current query with the given {@link Region}. + * + * @param domainClass the class type of the GemFire persistent entity to query; must not be {@literal null}. + * @param region the GemFire Region in which to query; must not be {@literal null}. + * @return a Query String with the FROM clause in the OQL statement evaluated and replaced with + * the fully-qualified Region to query. + * @see com.gemstone.gemfire.cache.Region + */ + @SuppressWarnings("unused") + public QueryString forRegion(Class domainClass, Region region) { + return new QueryString(query.replaceAll(REGION_PATTERN, region.getFullPath())); + } /** * Returns the parameter indexes used in this query. * * @return the parameter indexes used in this query or an empty {@link Iterable} if none are used. + * @see java.lang.Iterable */ public Iterable getInParameterIndexes() { Pattern pattern = Pattern.compile(IN_PARAMETER_PATTERN); @@ -116,6 +121,31 @@ class QueryString { return result; } + /** + * Appends the Sort order to this GemFire OQL Query string. + * + * @param sort the Sort object indicating the order by criteria. + * @return this QueryString with an ORDER BY clause if the Sort object is not null, or this QueryString as-is + * if the Sort object is null. + * @see org.springframework.data.domain.Sort + * @see org.springframework.data.gemfire.repository.query.QueryString + */ + public QueryString orderBy(Sort sort) { + if (sort != null) { + StringBuilder orderClause = new StringBuilder("ORDER BY "); + int count = 0; + + for (Sort.Order order : sort) { + orderClause.append(count++ > 0 ? ", " : ""); + orderClause.append(String.format("%1$s %2$s", order.getProperty(), order.getDirection())); + } + + return new QueryString(String.format("%1$s %2$s", this.query, orderClause.toString())); + } + + return this; + } + /* * (non-Javadoc) * @see java.lang.Object#toString() diff --git a/src/main/java/org/springframework/data/gemfire/repository/support/SimpleGemfireRepository.java b/src/main/java/org/springframework/data/gemfire/repository/support/SimpleGemfireRepository.java index 25f2da5d..1ef481be 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/support/SimpleGemfireRepository.java +++ b/src/main/java/org/springframework/data/gemfire/repository/support/SimpleGemfireRepository.java @@ -10,6 +10,7 @@ import org.springframework.data.gemfire.GemfireCallback; import org.springframework.data.gemfire.GemfireTemplate; import org.springframework.data.gemfire.repository.GemfireRepository; import org.springframework.data.gemfire.repository.Wrapper; +import org.springframework.data.gemfire.repository.query.QueryString; import org.springframework.data.repository.core.EntityInformation; import org.springframework.util.Assert; @@ -111,32 +112,15 @@ public class SimpleGemfireRepository implements Gemf */ @Override public Iterable findAll(final Sort sort) { - SelectResults selectResults = template.find(String.format("SELECT * FROM %1$s%2$s", - template.getRegion().getFullPath(), toString(sort))); + QueryString query = new QueryString("SELECT * FROM /RegionPlaceholder") + .forRegion(entityInformation.getJavaType(), template.getRegion()) + .orderBy(sort); + + SelectResults selectResults = template.find(query.toString()); + return selectResults.asList(); } - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Sort - */ - private String toString(final Sort sort) { - if (sort != null) { - StringBuilder orderClause = new StringBuilder(" ORDER BY "); - int count = 0; - - for (Sort.Order order : sort) { - orderClause.append(count++ > 0 ? ", " : ""); - orderClause.append(String.format("%1$s %2$s", order.getProperty(), order.getDirection())); - } - - return orderClause.toString(); - } - - return ""; - } - /* * (non-Javadoc) * diff --git a/src/test/java/org/springframework/data/gemfire/repository/query/QueryStringUnitTests.java b/src/test/java/org/springframework/data/gemfire/repository/query/QueryStringUnitTests.java index a03c614f..b5ac61c2 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/query/QueryStringUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/repository/query/QueryStringUnitTests.java @@ -16,6 +16,7 @@ package org.springframework.data.gemfire.repository.query; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -28,6 +29,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.domain.Sort; import org.springframework.data.gemfire.repository.sample.Person; import org.springframework.data.gemfire.repository.sample.RootUser; @@ -45,14 +47,26 @@ public class QueryStringUnitTests { @SuppressWarnings("rawtypes") Region region; + protected Sort.Order createOrder(final String property) { + return createOrder(property, Sort.Direction.ASC); + } + + protected Sort.Order createOrder(final String property, final Sort.Direction direction) { + return new Sort.Order(direction, property); + } + + protected Sort createSort(Sort.Order... orders) { + return new Sort(orders); + } + // SGF-251 @Test public void replacesDomainObjectWithRegionPathCorrectly() { QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname = $1"); - when(region.getFullPath()).thenReturn("/foo"); + when(region.getFullPath()).thenReturn("/foo/bar"); - assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo p WHERE p.firstname = $1")); + assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo/bar p WHERE p.firstname = $1")); verify(region, never()).getName(); } @@ -63,16 +77,16 @@ public class QueryStringUnitTests { public void replacesDomainObjectWithPluralRegionPathCorrectly() { QueryString query = new QueryString("SELECT * FROM /Persons p WHERE p.firstname = $1"); - when(region.getFullPath()).thenReturn("/Persons"); + when(region.getFullPath()).thenReturn("/People"); - assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /Persons p WHERE p.firstname = $1")); + assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /People p WHERE p.firstname = $1")); verify(region, never()).getName(); } // SGF-252 @Test - public void replacesFullyQualifiedSubegionReferenceWithRegionPathCorrectly() { + public void replacesFullyQualifiedSubregionReferenceWithRegionPathCorrectly() { QueryString query = new QueryString("SELECT * FROM //Local/Root/Users u WHERE u.username = $1"); when(region.getFullPath()).thenReturn("/Local/Root/Users"); @@ -96,4 +110,29 @@ public class QueryStringUnitTests { assertThat(indexes, is((Iterable) Arrays.asList(1, 2))); } + @Test + public void addsOrderByClauseCorrectly() { + QueryString query = new QueryString("SELECT * FROM /People p WHERE p.lastName = $1") + .orderBy(createSort(createOrder("lastName", Sort.Direction.DESC), createOrder("firstName"))); + + assertEquals("SELECT * FROM /People p WHERE p.lastName = $1 ORDER BY lastName DESC, firstName ASC", + query.toString()); + } + + @Test + public void addsSingleOrderByClauseCorrectly() { + QueryString query = new QueryString("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1") + .orderBy(createSort(createOrder("lastName"))); + + assertEquals("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1 ORDER BY lastName ASC", + query.toString()); + } + + @Test + public void addsNoOrderByClauseCorrectly() { + QueryString query = new QueryString("SELECT * FROM /People p").orderBy(null); + + assertEquals("SELECT * FROM /People p", query.toString()); + } + } diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepository.java b/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepository.java index 2e3b8795..0dcc5085 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepository.java +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepository.java @@ -16,7 +16,9 @@ package org.springframework.data.gemfire.repository.sample; import java.util.Collection; +import java.util.List; +import org.springframework.data.domain.Sort; import org.springframework.data.gemfire.repository.GemfireRepository; import org.springframework.data.gemfire.repository.Query; @@ -53,4 +55,9 @@ public interface PersonRepository extends GemfireRepository { Collection findByLastnameEndingWith(String lastname); Collection findByFirstnameContaining(String firstname); + + List findDistinctByLastname(String lastName, Sort order); + + List findDistinctPeopleByOrderByLastnameDesc(Sort order); + } diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest.java b/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest.java new file mode 100644 index 00000000..a0d35eb5 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.repository.sample; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * The PersonRepositoryTest class... + * + * @author John Blum + * @see org.junit.Test + * @see org.junit.runner.RunWith + * @see org.springframework.data.gemfire.repository.sample.Person + * @see org.springframework.data.gemfire.repository.sample.PersonRepository + * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner + * @since 1.4.0 + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +@SuppressWarnings("unused") +public class PersonRepositoryTest { + + protected final AtomicLong ID_SEQUENCE = new AtomicLong(0l); + + private Person cookieDoe = createPerson("Cookie", "Doe"); + private Person janeDoe = createPerson("Jane", "Doe"); + private Person jonDoe = createPerson("Jon", "Doe"); + private Person pieDoe = createPerson("Pie", "Doe"); + private Person jackHandy = createPerson("Jack", "Handy"); + private Person sandyHandy = createPerson("Sandy", "Handy"); + private Person imaPigg = createPerson("Ima", "Pigg"); + + @Autowired + private PersonRepository personRepo; + + @Before + public void setup() { + if (personRepo.count() == 0) { + sandyHandy = personRepo.save(sandyHandy); + jonDoe = personRepo.save(jonDoe); + jackHandy = personRepo.save(jackHandy); + janeDoe = personRepo.save(janeDoe); + pieDoe = personRepo.save(pieDoe); + imaPigg = personRepo.save(imaPigg); + cookieDoe = personRepo.save(cookieDoe); + } + + assertEquals(7l, personRepo.count()); + } + + protected Person createPerson(final String firstName, final String lastName) { + return new Person(ID_SEQUENCE.incrementAndGet(), firstName, lastName); + } + + protected Sort.Order createOrder(final String property) { + return createOrder(property, Sort.Direction.ASC); + } + + protected Sort.Order createOrder(final String property, final Sort.Direction direction) { + return new Sort.Order(direction, property); + } + + protected Sort createSort(final Sort.Order... orders) { + return new Sort(orders); + } + + @Test + public void testFindDistinctPeopleWithOrder() { + List actualPeople = personRepo.findDistinctPeopleByOrderByLastnameDesc( + createSort(createOrder("firstname"))); + + assertNotNull(actualPeople); + assertFalse(actualPeople.isEmpty()); + assertEquals(7, actualPeople.size()); + assertEquals(Arrays.asList(imaPigg, jackHandy, sandyHandy, cookieDoe, janeDoe, jonDoe, pieDoe), actualPeople); + } + + @Test + public void testFindDistinctPersonWithNoOrder() { + List actualPeople = personRepo.findDistinctByLastname("Pigg", null); + + assertNotNull(actualPeople); + assertFalse(actualPeople.isEmpty()); + assertEquals(1, actualPeople.size()); + assertEquals(String.format("Expected '%1$s'; but was '%2$s'", imaPigg, actualPeople.get(0)), + imaPigg, actualPeople.get(0)); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/repository/sample/SubRegionRepositoryIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/repository/sample/SubRegionRepositoryIntegrationTest.java index 2ffa2267..e89a6c8c 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/sample/SubRegionRepositoryIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/repository/sample/SubRegionRepositoryIntegrationTest.java @@ -213,14 +213,14 @@ public class SubRegionRepositoryIntegrationTest { assertNotNull(javaProgrammers); assertFalse(javaProgrammers.isEmpty()); assertEquals(2, javaProgrammers.size()); - assertTrue(javaProgrammers.containsAll(getProgrammers("JamesGosling", "JoshuaBloch"))); + assertEquals(javaProgrammers, getProgrammers("JamesGosling", "JoshuaBloch")); List groovyProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Groovy"); assertNotNull(groovyProgrammers); assertFalse(groovyProgrammers.isEmpty()); assertEquals(1, groovyProgrammers.size()); - assertTrue(groovyProgrammers.containsAll(getProgrammers("JamesStrachan"))); + assertEquals(groovyProgrammers, getProgrammers("JamesStrachan")); programmersRepo.save(new Wrapper(createProgrammer("RodJohnson", "Java"), "RodJohnson")); programmersRepo.save(new Wrapper(createProgrammer("GuillaumeLaforge", "Groovy"), "GuillaumeLaforge")); @@ -231,21 +231,21 @@ public class SubRegionRepositoryIntegrationTest { assertNotNull(javaProgrammers); assertFalse(javaProgrammers.isEmpty()); assertEquals(3, javaProgrammers.size()); - assertTrue(javaProgrammers.containsAll(getProgrammers("JamesGosling", "JoshuaBloch", "RodJohnson"))); + assertEquals(javaProgrammers, getProgrammers("JamesGosling", "JoshuaBloch", "RodJohnson")); groovyProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Groovy"); assertNotNull(groovyProgrammers); assertFalse(groovyProgrammers.isEmpty()); assertEquals(3, groovyProgrammers.size()); - assertTrue(groovyProgrammers.containsAll(getProgrammers("GraemeRocher", "GuillaumeLaforge", "JamesStrachan"))); + assertEquals(groovyProgrammers, getProgrammers("GraemeRocher", "GuillaumeLaforge", "JamesStrachan")); List javaLikeProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Java%"); assertNotNull(javaLikeProgrammers); assertFalse(javaLikeProgrammers.isEmpty()); assertEquals(4, javaLikeProgrammers.size()); - assertTrue(javaLikeProgrammers.containsAll(getProgrammers("BrendanEich", "JamesGosling", "JoshuaBloch", "RodJohnson"))); + assertEquals(javaLikeProgrammers, getProgrammers("BrendanEich", "JamesGosling", "JoshuaBloch", "RodJohnson")); List pseudoCodeProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("PseudoCode"); diff --git a/src/test/resources/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest-context.xml new file mode 100644 index 00000000..a726db4b --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/repository/sample/PersonRepositoryTest-context.xml @@ -0,0 +1,31 @@ + + + + + springGemFirePersonRepositoryTest + 0 + config + + + + + + + + + + +