diff --git a/pom.xml b/pom.xml index 6a81501ac0..4fde8a2928 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-commons - 2.3.0.BUILD-SNAPSHOT + 2.3.0.DATACMNS-1596-SNAPSHOT Spring Data Core diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java index ecc0ad3ca5..2301f3e2a8 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.Set; import java.util.function.Supplier; +import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -53,7 +54,9 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryConfigurationExtensionSupport.class); private static final String CLASS_LOADING_ERROR = "%s - Could not load type %s using class loader %s."; - private static final String MULTI_STORE_DROPPED = "Spring Data {} - Could not safely identify store assignment for repository candidate {}."; + private static final String MULTI_STORE_DROPPED = "Spring Data %s - Could not safely identify store assignment for repository candidate %s. If you want this repository to be a %s repository,"; + + private boolean noMultiStoreSupport = false; /* * (non-Javadoc) @@ -294,7 +297,22 @@ protected RepositoryConfiguration g */ protected boolean isStrictRepositoryCandidate(RepositoryMetadata metadata) { + if (noMultiStoreSupport) { + return false; + } + Collection> types = getIdentifyingTypes(); + Collection> annotations = getIdentifyingAnnotations(); + String moduleName = getModuleName(); + + if (types.isEmpty() && annotations.isEmpty()) { + if (!noMultiStoreSupport) { + LOGGER.warn("Spring Data {} does not support multi-store setups!", moduleName); + noMultiStoreSupport = true; + return false; + } + } + Class repositoryInterface = metadata.getRepositoryInterface(); for (Class type : types) { @@ -304,11 +322,6 @@ protected boolean isStrictRepositoryCandidate(RepositoryMetadata metadata) { } Class domainType = metadata.getDomainType(); - Collection> annotations = getIdentifyingAnnotations(); - - if (annotations.isEmpty()) { - return true; - } for (Class annotationType : annotations) { if (AnnotationUtils.findAnnotation(domainType, annotationType) != null) { @@ -316,7 +329,23 @@ protected boolean isStrictRepositoryCandidate(RepositoryMetadata metadata) { } } - LOGGER.info(MULTI_STORE_DROPPED, getModuleName(), repositoryInterface); + String message = String.format(MULTI_STORE_DROPPED, moduleName, repositoryInterface, moduleName); + + if (!annotations.isEmpty()) { + message = message.concat(" consider annotating your entities with one of these annotations: ") // + .concat(toString(annotations)) // + .concat(types.isEmpty() ? "." : " (preferred)"); + } + + if (!types.isEmpty()) { + + message = message.concat(annotations.isEmpty() ? " consider" : ", or consider") // + .concat(" extending one of the following types with your repository: ") // + .concat(toString(types)) // + .concat("."); + } + + LOGGER.info(message); return false; } @@ -364,4 +393,11 @@ private Class loadRepositoryInterface(RepositoryConfiguration configuratio return null; } + + private static String toString(Collection> types) { + + return types.stream() // + .map(Class::getName) // + .collect(Collectors.joining(", ")); + } } diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java index 1e8a0670ea..7da9f71068 100755 --- a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java @@ -34,9 +34,11 @@ import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.AbstractRepositoryMetadata; +import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.data.repository.reactive.ReactiveCrudRepository; @@ -86,6 +88,15 @@ public void rejectsReactiveRepositories() { .hasMessageContaining("Reactive Repositories are not supported"); } + @Test // DATACMNS-1596 + public void doesNotClaimEntityIfNoIdentifyingAnnotationsAreExposed() { + + NonIdentifyingConfigurationExtension extension = new NonIdentifyingConfigurationExtension(); + RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(AnnotatedTypeRepository.class); + + assertThat(extension.isStrictRepositoryCandidate(metadata)).isFalse(); + } + static class SampleRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { @Override @@ -109,6 +120,24 @@ protected Collection> getIdentifyingTypes() { } } + static class NonIdentifyingConfigurationExtension extends RepositoryConfigurationExtensionSupport { + + @Override + protected String getModulePrefix() { + return "non-identifying"; + } + + @Override + public String getRepositoryFactoryBeanClassName() { + return RepositoryFactoryBeanSupport.class.getName(); + } + + @Override + protected Collection> getIdentifyingTypes() { + return Collections.singleton(CrudRepository.class); + } + } + @Primary static class AnnotatedType {}