From 48d4c05a9d3713d5f7a9936be151665b0b0b39f5 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 20 Dec 2011 12:29:38 +0100 Subject: [PATCH] DATACMNS-114 - Improved detection of custom implementations for repositories. Fixed edge case scenario where the lookup for repository implementation classes picked up multiple classes if they ended with the same suffix (e.g. FooRepoImpl, AnotherFooRepoImpl). We're now expecting the classname to be an exact match but still allow nested packages. Changed the parser to reject multiple found implementation classes strictly now to at least avoid undiscoverable errors in case an ambiguity is popping up. --- ...tractRepositoryConfigDefinitionParser.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/AbstractRepositoryConfigDefinitionParser.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/AbstractRepositoryConfigDefinitionParser.java index e1c7d6073..0039d57dc 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/AbstractRepositoryConfigDefinitionParser.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/AbstractRepositoryConfigDefinitionParser.java @@ -21,7 +21,9 @@ import static org.springframework.data.repository.util.ClassUtils.*; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.regex.Pattern; @@ -46,6 +48,7 @@ import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.core.type.filter.RegexPatternTypeFilter; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.RepositoryDefinition; +import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** @@ -264,15 +267,30 @@ public abstract class AbstractRepositoryConfigDefinitionParser definitions = provider.findCandidateComponents(config.getBasePackage()); + + if (definitions.size() == 0) { + return null; + } + + if (definitions.size() == 1) { + return (AbstractBeanDefinition) definitions.iterator().next(); + } - return (0 == definitions.size() ? null : (AbstractBeanDefinition) definitions.iterator().next()); + List implementationClassNames = new ArrayList(); + for (BeanDefinition bean : definitions) { + implementationClassNames.add(bean.getBeanClassName()); + } + + throw new IllegalStateException(String.format( + "Ambiguous custom implementations detected! Found %s but expected a single implementation!", + StringUtils.collectionToCommaDelimitedString(implementationClassNames))); } /**