diff --git a/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java b/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java index 63d09589..b520660c 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java +++ b/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java @@ -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. diff --git a/src/main/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactory.java b/src/main/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactory.java index 8cd664f7..aeeeba42 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactory.java +++ b/src/main/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactory.java @@ -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 entityInformation = getEntityInformation(metadata.getDomainType()); - GemfireTemplate gemfireTemplate = getTemplate(metadata); - return new SimpleGemfireRepository(gemfireTemplate, entityInformation); + protected Object getTargetRepository(RepositoryInformation repositoryInformation) { + GemfireEntityInformation 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) */ diff --git a/src/test/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactoryUnitTests.java b/src/test/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactoryUnitTests.java index 43599a89..dcc4047b 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/repository/support/GemfireRepositoryFactoryUnitTests.java @@ -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> regions = new ArrayList>(); - regions.add(region); - - GemfireMappingContext context = new GemfireMappingContext(); - - GemfireRepositoryFactory factory = new GemfireRepositoryFactory(regions, context); + GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory( + Collections.>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 { + @Test + public void usesConfiguredRepositoryBaseClass() { + GemfireRepositoryFactory repositoryFactory = new GemfireRepositoryFactory( + Collections.>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 { + interface SamplePagingAndSortingRepository extends PagingAndSortingRepository { + } + + interface SamplePagingRepository extends Repository { Page findAll(Pageable pageable); } - interface SampleSortingInterface extends Repository { + interface SampleSortingRepository extends Repository { Iterable findAll(Sort sort); } + interface SampleCustomRepository { + void doCustomUpdate(T entity); + } + + class SampleCustomRepositoryImpl implements SampleCustomRepository { + + @Override + public void doCustomUpdate(final T entity) { + throw new UnsupportedOperationException("Not Implemented!"); + } + } + + interface SampleCustomGemfireRepository extends GemfireRepository, SampleCustomRepository { + } + + static class CustomBaseRepository extends SimpleGemfireRepository { + + public CustomBaseRepository(GemfireTemplate template, EntityInformation entityInformation) { + super(template, entityInformation); + } + } + }