0

I'm Aware that this issue is almost the same as solved in this answer but it's not working for me and my setup is also a bit different.

I want to choose between two implementations of the FooRepository interface. For this, I created the RepositoryManager Configuration. In theory, only one bean should exist at runtime because of the excluding conditions.

In all cases, the "postgres.active" property is set to false.

@Configuration
public class RepositoryManager {

   @Bean(name = "repositoryQualifier")
   @ConditionalOnProperty(
           value="postgres.active",
           havingValue = "true")
   public FooRepository managedRepository(PostgresRepository postgresRepository){
       return postgresRepository;
   }

   @Bean(name = "repositoryQualifier")
   @ConditionalOnProperty(
           value="postgres.active",
           havingValue = "false")
   public FooRepository managedRepository(RedisRepository redisRepository){
       return  redisRepository;
   }
}
@RestController
public class BarService{

    private final FooRepository repository;


    @Autowired
    public BarService(
            @Qualifier("repositoryQualifier") final FooRepository repository,
    ) {
        this.repository = repository;
    }
}

When I try to run this example Spring throws this error:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying
bean of type 'org.test.FooRepository' available: expected 
at least 1 bean which qualifies as autowire candidate. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Qualifier(value="repositoryQualifier")

If I comment one of the Beans and remove the condition from the not commented one it finds the bean so it shouldn't be an issue with locating the package or the bean. I'm desperate, I'm already struggling with this for 6h now

maxiangelo
  • 125
  • 12
  • Have you tried with a breakpoint in the condition evaluation? There you should see why it‘s ignored. Probably you have a typo or a whitespace somewhere? – Martin Frey Jul 07 '21 at 19:54
  • @MartinFrey I just tried setting a breakpoint in the condition but it didn't break, I'm using Intellij – maxiangelo Jul 07 '21 at 20:57

2 Answers2

2

PostgresRepository and RedisRepository are subclasses of or implement FooRepository, right? please try out if it works without specifying an explicit bean name in the @Bean annotations - also it might also be an option to use @ConditionalOnExpression instead but ofc your way should basically also work just fine, e.g. as follows:

@Configuration
public class RepositoryManager {

   @Bean
   @ConditionalOnExpression("${postgres.active}")
   public FooRepository managedRepository(PostgresRepository postgresRepository){
       return postgresRepository;
   }

   @Bean
   @ConditionalOnExpression("!${postgres.active}")
   public FooRepository managedRepository(RedisRepository redisRepository){
       return  redisRepository;
   }
}

@RestController
public class BarService{

    private final FooRepository repository;

    @Autowired
    public BarService(final FooRepository repository,
    ) {
        this.repository = repository;
    }
}
  • Thats tricky because PostgresRepository and RedisRepository are also beans that implement FooRepository so spring says it has found multiple possible beans and then crashes. This is why I'm using the qualifiers. – maxiangelo Jul 07 '21 at 20:36
  • I also tried most of the possible condition annotations and none of them changed the outcome. – maxiangelo Jul 07 '21 at 20:37
0

Maybe try using the Bean name:

@Autowired
    public BarService(@Qualifier("repositoryQualifier") FooRepository managedRepository) {
repository = managedRepository;
}

Also, why are you using the same Qualifier name for both methods ? Try also to change the name of the second method.

epushor
  • 66
  • 6
  • Its using the same name because one of them should not exist at runtime. Only the one where the condition is met should be existent at runtime. – maxiangelo Jul 07 '21 at 20:33
  • Also had the idea with just using the method name but it had the same result. – maxiangelo Jul 07 '21 at 20:39