From 4eff4235bd78b9fb2631145a9a47d24f4ea83659 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 24 Oct 2019 12:46:22 +0200 Subject: [PATCH 1/2] DATACMNS-1596 - Prepare feature branch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 4e29b4571969eed2cc427f092e7b6b2f027d8a98 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 24 Oct 2019 13:35:48 +0200 Subject: [PATCH 2/2] DATACMNS-1596 - Modules not exposing identifying annotations do not claim repository interfaces anymore. Previously, a module not exposing any entity identifying annotations would have claimed a repository definition and potentially overrode the bean definition of another store that was the proper claim in the first place. We have now changed this to abstain from a claim of the interface. We' also tweaked the log output in the following cases: 1. If the module neither returns an identifying type nor entity identifying annotations, we now log a warning that a module does not support a multi-module setup and answer all assignment requests with false. 2. The info level warning indicating an interface has been dropped now reports which annotations or interface base types to use. Original pull request: #411. Related tickets: spring-projects/spring-boot#18721 --- ...positoryConfigurationExtensionSupport.java | 50 ++++++++++++++++--- ...onfigurationExtensionSupportUnitTests.java | 29 +++++++++++ 2 files changed, 72 insertions(+), 7 deletions(-) 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 {}