Fixes JIRA issue SGF-277 - OQL Join in Repository Interface.
This commit is contained in:
@@ -60,10 +60,10 @@ public class PartTreeGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
ParametersParameterAccessor parameterAccessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
QueryString query = new GemfireQueryCreator(tree, method.getPersistentEntity()).createQuery(parameterAccessor
|
||||
.getSort());
|
||||
|
||||
QueryString query = new GemfireQueryCreator(tree, method.getPersistentEntity())
|
||||
.createQuery(parameterAccessor.getSort());
|
||||
|
||||
RepositoryQuery repositoryQuery = new StringBasedGemfireRepositoryQuery(query.toString(), method, template);
|
||||
|
||||
|
||||
@@ -21,23 +21,23 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Value object to work with OQL query strings.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class QueryString {
|
||||
|
||||
//private static final String REGION_PATTERN = "(?<=\\/)\\w+";
|
||||
private static final String REGION_PATTERN = "\\/(\\/?\\w)+";
|
||||
private static final String IN_PARAMETER_PATTERN = "(?<=IN (SET|LIST) \\$)\\d";
|
||||
private static final String IN_PATTERN = "(?<=IN (SET|LIST) )\\$\\d";
|
||||
private static final String IN_PARAMETER_PATTERN = "(?<=IN (SET|LIST) \\$)\\d";
|
||||
private static final String REGION_PATTERN = "\\/(\\/?\\w)+";
|
||||
|
||||
private final String query;
|
||||
|
||||
@@ -47,8 +47,7 @@ class QueryString {
|
||||
* @param source
|
||||
*/
|
||||
public QueryString(String source) {
|
||||
|
||||
Assert.hasText(source);
|
||||
Assert.hasText(source, "The OQL statement (Query) to execute must be specified!");
|
||||
this.query = source;
|
||||
}
|
||||
|
||||
@@ -57,7 +56,8 @@ class QueryString {
|
||||
*
|
||||
* @param domainClass must not be {@literal null}.
|
||||
*/
|
||||
public QueryString(Class<?> domainClass) {
|
||||
@SuppressWarnings("unused")
|
||||
public QueryString(Class<?> domainClass) {
|
||||
this(domainClass, false);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ 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()));
|
||||
this(String.format(isCountQuery ? "SELECT count(*) FROM /%s" : "SELECT * FROM /%s", domainClass.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +78,7 @@ class QueryString {
|
||||
* @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()));
|
||||
}
|
||||
@@ -90,23 +90,21 @@ class QueryString {
|
||||
* @param values the values to bind, returns the {@link QueryString} as is if {@literal null} is given.
|
||||
* @return
|
||||
*/
|
||||
public QueryString bindIn(Collection<?> 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)));
|
||||
}
|
||||
|
||||
if (values == null) {
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'");
|
||||
return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString)));
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public Iterable<Integer> getInParameterIndexes() {
|
||||
|
||||
Pattern pattern = Pattern.compile(IN_PARAMETER_PATTERN);
|
||||
Matcher matcher = pattern.matcher(query);
|
||||
List<Integer> result = new ArrayList<Integer>();
|
||||
@@ -126,4 +124,5 @@ class QueryString {
|
||||
public String toString() {
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,13 @@ import com.gemstone.gemfire.cache.query.internal.ResultsBag;
|
||||
*/
|
||||
public class StringBasedGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
|
||||
private static final String INVALID_EXECUTION = "Paging and modifying queries are not supported!";
|
||||
private static final String INVALID_QUERY = "Paging and modifying queries are not supported!";
|
||||
|
||||
private boolean userDefinedQuery = false;
|
||||
|
||||
private final QueryString query;
|
||||
private final GemfireQueryMethod method;
|
||||
private final GemfireTemplate template;
|
||||
private final QueryString query;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -69,34 +71,50 @@ public class StringBasedGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
* Creates a new {@link StringBasedGemfireRepositoryQuery} using the given query {@link String},
|
||||
* {@link GemfireQueryMethod} and {@link GemfireTemplate}.
|
||||
*
|
||||
* @param query will fall back to the query annotated to the given {@link GemfireQueryMethod} if {@literal null} is
|
||||
* given.
|
||||
* @param query will fall back to the query annotated to the given {@link GemfireQueryMethod} if {@literal null}.
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedGemfireRepositoryQuery(String query, GemfireQueryMethod method, GemfireTemplate template) {
|
||||
|
||||
super(method);
|
||||
|
||||
Assert.notNull(template);
|
||||
|
||||
this.userDefinedQuery |= !StringUtils.hasText(query);
|
||||
this.query = new QueryString(StringUtils.hasText(query) ? query : method.getAnnotatedQuery());
|
||||
this.method = method;
|
||||
this.template = template;
|
||||
|
||||
if (method.isPageQuery() || method.isModifyingQuery()) {
|
||||
throw new IllegalStateException(INVALID_EXECUTION);
|
||||
throw new IllegalStateException(INVALID_QUERY);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*/
|
||||
public StringBasedGemfireRepositoryQuery asUserDefinedQuery() {
|
||||
this.userDefinedQuery = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*/
|
||||
public boolean isUserDefinedQuery() {
|
||||
return userDefinedQuery;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
ParametersParameterAccessor accessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
QueryString query = this.query.forRegion(method.getEntityInformation().getJavaType(), template.getRegion());
|
||||
|
||||
QueryString query = (isUserDefinedQuery() ? this.query :
|
||||
this.query.forRegion(method.getEntityInformation().getJavaType(), template.getRegion()));
|
||||
|
||||
for (Integer index : query.getInParameterIndexes()) {
|
||||
query = query.bindIn(toCollection(accessor.getBindableValue(index - 1)));
|
||||
|
||||
@@ -147,18 +147,18 @@ public class GemfireRepositoryFactory extends RepositoryFactorySupport {
|
||||
return new QueryLookupStrategy() {
|
||||
@Override
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
|
||||
|
||||
GemfireQueryMethod queryMethod = new GemfireQueryMethod(method, metadata, context);
|
||||
GemfireTemplate template = getTemplate(metadata);
|
||||
|
||||
if (queryMethod.hasAnnotatedQuery()) {
|
||||
return new StringBasedGemfireRepositoryQuery(queryMethod, template);
|
||||
return new StringBasedGemfireRepositoryQuery(queryMethod, template).asUserDefinedQuery();
|
||||
}
|
||||
|
||||
String namedQueryName = queryMethod.getNamedQueryName();
|
||||
|
||||
if (namedQueries.hasQuery(namedQueryName)) {
|
||||
return new StringBasedGemfireRepositoryQuery(namedQueries.getQuery(namedQueryName), queryMethod,
|
||||
template);
|
||||
template).asUserDefinedQuery();
|
||||
}
|
||||
|
||||
return new PartTreeGemfireRepositoryQuery(queryMethod, template);
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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 org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.Region;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The Account class is an abstract data type (ADT) for modeling customer accounts.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.mapping.Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Region("Accounts")
|
||||
@SuppressWarnings("unused")
|
||||
public class Account {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private Long customerId;
|
||||
|
||||
private String number;
|
||||
|
||||
public Account(final Long customerId) {
|
||||
Assert.notNull(customerId, "The Customer ID to which this Account is associated cannot be null!");
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Account(final Customer customer) {
|
||||
this(customer.getId());
|
||||
}
|
||||
|
||||
public Account(final Long customerId, final String number) {
|
||||
this(customerId);
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Account(final Customer customer, final String number) {
|
||||
this(customer);
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Account(final Long accountId, final Long customerId) {
|
||||
this(customerId);
|
||||
this.id = accountId;
|
||||
}
|
||||
|
||||
public Account(final Long accountId, final Customer customer) {
|
||||
this(customer);
|
||||
this.id = accountId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(final Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(final String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Customer (%1$d) Account (%2$d) #(%3$s)", getCustomerId(), getId(), getNumber());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
|
||||
/**
|
||||
* The AccountsRepository class is a Data Access Object (DAO) for accessing and performing persistent operations on
|
||||
* Account objects.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.repository.sample.Account
|
||||
* @see org.springframework.data.gemfire.repository.GemfireRepository
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface AccountRepository extends GemfireRepository<Account, Long> {
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @since 1.4.0
|
||||
* @link https://github.com/spring-projects/spring-data-gemfire/pull/55
|
||||
*/
|
||||
@ContextConfiguration("AnimalRepositoryTest-context.xml")
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class AnimalRepositoryTest {
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface CatRepository extends GemfireRepository<Animal, Long> {
|
||||
|
||||
Animal findByName(String name);
|
||||
|
||||
@Query("SELECT * FROM /Animals x WHERE x.name = $1")
|
||||
@Query("SELECT * FROM /Cats x WHERE x.name = $1")
|
||||
Animal findBy(String name);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.Region;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* The Customer class is a class abstraction modeling a Customer.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see org.springframework.data.gemfire.mapping.Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Region("Customers")
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Customer(final String firstName, final String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(final String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
protected static boolean equalsIgnoreNull(final Object obj1, final Object obj2) {
|
||||
return (obj1 == null ? obj2 == null : obj1.equals(obj2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Customer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Customer that = (Customer) obj;
|
||||
|
||||
return equalsIgnoreNull(this.getId(), that.getId())
|
||||
&& ObjectUtils.nullSafeEquals(this.getFirstName(), that.getFirstName())
|
||||
&& ObjectUtils.nullSafeEquals(this.getLastName(), that.getLastName());
|
||||
}
|
||||
|
||||
protected static int hashCodeIgnoreNull(final Object obj) {
|
||||
return (obj != null ? obj.hashCode() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashValue = 17;
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId());
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getFirstName());
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getLastName());
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%1$s %2$s", getFirstName(), getLastName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 java.util.List;
|
||||
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
|
||||
/**
|
||||
* The CustomerRepository class is a Data Access Object (DAO) for accessing and performing persistent operations on
|
||||
* Customer objects.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.repository.sample.Customer
|
||||
* @see org.springframework.data.gemfire.repository.GemfireRepository
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface CustomerRepository extends GemfireRepository<Customer, Long> {
|
||||
|
||||
@Query("SELECT DISTINCT c FROM /Customers c, /Accounts a WHERE c.id = a.customerId")
|
||||
List<Customer> findCustomersWithAccounts();
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public interface DogRepository extends GemfireRepository<Animal, Long> {
|
||||
|
||||
Animal findByName(String name);
|
||||
|
||||
@Query("SELECT * FROM /Animals x WHERE x.name = $1")
|
||||
@Query("SELECT * FROM /Dogs x WHERE x.name = $1")
|
||||
Animal findBy(String name);
|
||||
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ import org.springframework.data.gemfire.repository.Query;
|
||||
*/
|
||||
public interface PersonRepository extends GemfireRepository<Person, Long> {
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname = $1")
|
||||
@Query("SELECT * FROM /simple p WHERE p.firstname = $1")
|
||||
Collection<Person> findByFirstnameAnnotated(String firstname);
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname IN SET $1")
|
||||
@Query("SELECT * FROM /simple p WHERE p.firstname IN SET $1")
|
||||
Collection<Person> findByFirstnamesAnnotated(Collection<String> firstnames);
|
||||
|
||||
Collection<Person> findByFirstname(String firstname);
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* The RepositoryQueriesWithJoinsTest class is a test suite of test cases testing the use of JOINS between 2 Regions
|
||||
* in GemFire OQL queries (SELECT statements).
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ContextConfiguration("repositoryQueriesWithJoins.xml")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class RepositoryQueriesWithJoinsIntegrationTest {
|
||||
|
||||
private static final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
|
||||
|
||||
@Autowired
|
||||
private AccountRepository accountRepo;
|
||||
|
||||
@Autowired
|
||||
private CustomerRepository customerRepo;
|
||||
|
||||
protected Account createAccount(final Customer customer, final String number) {
|
||||
Account account = new Account(ID_SEQUENCE.incrementAndGet(), customer);
|
||||
account.setNumber(number);
|
||||
return account;
|
||||
}
|
||||
|
||||
protected Customer createCustomer(final String firstName, final String lastName) {
|
||||
Customer customer = new Customer(firstName, lastName);
|
||||
customer.setId(ID_SEQUENCE.incrementAndGet());
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinQueries() {
|
||||
Customer jonDoe = customerRepo.save(createCustomer("Jon", "Doe"));
|
||||
Customer janeDoe = customerRepo.save(createCustomer("Jane", "Doe"));
|
||||
Customer jackHandy = customerRepo.save(createCustomer("Jack", "Handy"));
|
||||
|
||||
Account jonAccountOne = accountRepo.save(createAccount(jonDoe, "1"));
|
||||
Account jonAccountTwo = accountRepo.save(createAccount(jonDoe, "2"));
|
||||
Account janeAccount = accountRepo.save(createAccount(janeDoe, "1"));
|
||||
|
||||
List<Customer> actualCustomersWithAccounts = customerRepo.findCustomersWithAccounts();
|
||||
List<Customer> expectedCustomersWithAccounts = Arrays.asList(jonDoe, janeDoe);
|
||||
|
||||
assertNotNull(actualCustomersWithAccounts);
|
||||
assertFalse(String.format("Expected Customers (%1$s)!", expectedCustomersWithAccounts),
|
||||
actualCustomersWithAccounts.isEmpty());
|
||||
assertEquals(String.format("Expected Customers (%1$s); but was (%2$s)!", expectedCustomersWithAccounts, actualCustomersWithAccounts),
|
||||
2, actualCustomersWithAccounts.size());
|
||||
assertTrue(String.format("Expected Customers (%1$s); but was (%2$s)!", expectedCustomersWithAccounts, actualCustomersWithAccounts),
|
||||
actualCustomersWithAccounts.containsAll(expectedCustomersWithAccounts));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
|
||||
xmlns:repo="http://www.springframework.org/schema/data/repository"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd
|
||||
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="gemfireConfigurationSettings">
|
||||
<prop key="name">RepositoryQueriesWithJoinsIntegrationTest</prop>
|
||||
<prop key="log-level">config</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireConfigurationSettings"/>
|
||||
|
||||
<gfe:replicated-region id="Customers" persistent="false" key-constraint="java.lang.Long"
|
||||
value-constraint="org.springframework.data.gemfire.repository.sample.Customer"/>
|
||||
|
||||
<gfe:replicated-region id="Accounts" persistent="false" key-constraint="java.lang.Long"
|
||||
value-constraint="org.springframework.data.gemfire.repository.sample.Account"/>
|
||||
|
||||
<gfe-data:repositories base-package="org.springframework.data.gemfire.repository.sample">
|
||||
<repo:include-filter type="assignable" expression="org.springframework.data.gemfire.repository.sample.AccountRepository"/>
|
||||
<repo:include-filter type="assignable" expression="org.springframework.data.gemfire.repository.sample.CustomerRepository"/>
|
||||
</gfe-data:repositories>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user