My project has the following two repositories and a service class:
@Repository
public interface FooRepository extends JpaRepository<Foo, Long> {...}
@Repository
public interface FooExtRepository extends FooRepository {...}
@Service
public class FooService {
private final FooRepository fooRepository;
public FooService(FooRepository fooRepository, ...){...}
...
}
After I compile the project, I get the following error.
Parameter 2 of constructor in FooService required a single bean, but 2 were found:
- fooExtRepository: defined in FooRepositoryExt defined in @EnableJpaRepositories declared on DatabaseConfiguration
- fooRepository: defined in FooRepository defined in @EnableJpaRepositories declared on DatabaseConfiguration
This may be due to missing parameter name information
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
The FooService only asks for the FooRepository bean, but not the FooExtRepository. Why does the Spring find both Beans for the FooRepository bean injection in the FooService class? From the object-oriented programming point of view, an instance of the FooRepository and an instance of the FooExtRepository are not the same object.
To resolve this compiling error, I replace the FooRepository with the FooExtRepository.
Both your beans implement
FooRepositorywhich is why they're candidates for autowiring. This is nothing specific to Spring Data actually, but how the Spring Dependency Injection container works fundamentally.If you always want the
FooRepositoryinjected in such scenarios, follow the advice given in the error message and annotate that with@Primary. This will still allowFooExtRepositoryto be wired where referenced explicitly as for that injection point, there's only one candidate to begin with.