SGF-403 - Simplify the process of adding custom methods to Spring Data GemFire Repositories.
This commit is contained in:
@@ -27,6 +27,7 @@ import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
|
||||
@@ -119,6 +120,13 @@ public @interface EnableGemfireRepositories {
|
||||
*/
|
||||
Class<?> repositoryFactoryBeanClass() default GemfireRepositoryFactoryBean.class;
|
||||
|
||||
/**
|
||||
* Configure the repository base class to be used to create repository proxies for this particular configuration.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;
|
||||
|
||||
/**
|
||||
* Configures the name of the {@link GemfireMappingContext} bean definition to be used to create repositories
|
||||
* discovered through this annotation. If not configured a default one will be created.
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.gemfire.repository.query.PartTreeGemfireReposito
|
||||
import org.springframework.data.gemfire.repository.query.StringBasedGemfireRepositoryQuery;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
@@ -88,10 +89,13 @@ public class GemfireRepositoryFactory extends RepositoryFactorySupport {
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
GemfireEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
|
||||
GemfireTemplate gemfireTemplate = getTemplate(metadata);
|
||||
return new SimpleGemfireRepository(gemfireTemplate, entityInformation);
|
||||
protected Object getTargetRepository(RepositoryInformation repositoryInformation) {
|
||||
GemfireEntityInformation<?, Serializable> entityInformation = getEntityInformation(
|
||||
repositoryInformation.getDomainType());
|
||||
|
||||
GemfireTemplate gemfireTemplate = getTemplate(repositoryInformation);
|
||||
|
||||
return getTargetRepositoryViaReflection(repositoryInformation, gemfireTemplate, entityInformation);
|
||||
}
|
||||
|
||||
private GemfireTemplate getTemplate(RepositoryMetadata metadata) {
|
||||
@@ -139,7 +143,7 @@ public class GemfireRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see springframework.data.repository.core.support.RepositoryFactorySupport
|
||||
* #getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key)
|
||||
*/
|
||||
|
||||
@@ -15,24 +15,30 @@
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.RegionAttributes;
|
||||
@@ -55,42 +61,78 @@ public class GemfireRepositoryFactoryUnitTests {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private RegionAttributes attributes;
|
||||
|
||||
@Before
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setup() {
|
||||
when(region.getName()).thenReturn("simple");
|
||||
when(region.getFullPath()).thenReturn("/simple");
|
||||
when(region.getAttributes()).thenReturn(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://jira.spring.io/browse/SGF-112
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void rejectsInterfacesExtendingPagingAndSortingRepository() {
|
||||
|
||||
when(region.getName()).thenReturn("simple");
|
||||
when(region.getAttributes()).thenReturn(attributes);
|
||||
|
||||
List<Region<?, ?>> regions = new ArrayList<Region<?, ?>>();
|
||||
regions.add(region);
|
||||
|
||||
GemfireMappingContext context = new GemfireMappingContext();
|
||||
|
||||
GemfireRepositoryFactory factory = new GemfireRepositoryFactory(regions, context);
|
||||
GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singletonList(region), new GemfireMappingContext());
|
||||
|
||||
try {
|
||||
factory.getRepository(SampleInterface.class);
|
||||
//factory.getRepository(SamplePagingInterface.class);
|
||||
//factory.getRepository(SampleSortingInterface.class);
|
||||
} catch (IllegalStateException expected) {
|
||||
assertThat(expected.getMessage(), Matchers.startsWith("Pagination is not supported by Gemfire repositories!"));
|
||||
repositoryFactory.getRepository(SamplePagingAndSortingRepository.class);
|
||||
//factory.getRepository(SamplePagingRepository.class);
|
||||
//factory.getRepository(SampleSortingRepository.class);
|
||||
}
|
||||
catch (IllegalStateException expected) {
|
||||
assertThat(expected.getMessage(), Matchers.startsWith(
|
||||
"Pagination is not supported by Gemfire repositories!"));
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleInterface extends PagingAndSortingRepository<Person, Long> {
|
||||
@Test
|
||||
public void usesConfiguredRepositoryBaseClass() {
|
||||
GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory(
|
||||
Collections.<Region<?, ?>>singletonList(region), new GemfireMappingContext());
|
||||
|
||||
repositoryFactory.setRepositoryBaseClass(CustomBaseRepository.class);
|
||||
|
||||
GemfireRepository<?, ?> gemfireRepository = repositoryFactory.getRepository(SampleCustomGemfireRepository.class,
|
||||
new SampleCustomRepositoryImpl());
|
||||
|
||||
assertSame(CustomBaseRepository.class, ((Advised) gemfireRepository).getTargetClass());
|
||||
}
|
||||
|
||||
interface SamplePagingInterface extends Repository<Person, Long> {
|
||||
interface SamplePagingAndSortingRepository extends PagingAndSortingRepository<Person, Long> {
|
||||
}
|
||||
|
||||
interface SamplePagingRepository extends Repository<Person, Long> {
|
||||
Page<Person> findAll(Pageable pageable);
|
||||
}
|
||||
|
||||
interface SampleSortingInterface extends Repository<Person, Long> {
|
||||
interface SampleSortingRepository extends Repository<Person, Long> {
|
||||
Iterable<Person> findAll(Sort sort);
|
||||
}
|
||||
|
||||
interface SampleCustomRepository<T> {
|
||||
void doCustomUpdate(T entity);
|
||||
}
|
||||
|
||||
class SampleCustomRepositoryImpl<T> implements SampleCustomRepository<T> {
|
||||
|
||||
@Override
|
||||
public void doCustomUpdate(final T entity) {
|
||||
throw new UnsupportedOperationException("Not Implemented!");
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleCustomGemfireRepository extends GemfireRepository<Person, Long>, SampleCustomRepository<Person> {
|
||||
}
|
||||
|
||||
static class CustomBaseRepository<T, ID extends Serializable> extends SimpleGemfireRepository<T, ID> {
|
||||
|
||||
public CustomBaseRepository(GemfireTemplate template, EntityInformation<T, ID> entityInformation) {
|
||||
super(template, entityInformation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user