Manish
Manish

Reputation: 1519

How to resolve NonUniqueBeanException: Multiple possible bean candidates found in micron

I am getting NonUniqueBeanException: Multiple possible bean candidates found: for the below Micronaut code:

@Context
@Slf4j
@AllArgsConstructor
public class RemoteService {
   private final Provider<Session> remoteSessionFactory;
}

I have 2 implementations for the Provider

@Slf4j
@Prototype
@AllArgsConstructor
public class RemoteSessionFactoryA implements Provider<Session> {
    //some code here
}

@Slf4j
@Prototype
@AllArgsConstructor
public class RemoteSessionFactoryB implements Provider<Session> {
    //some code here
}

I have even tried like this but still getting the same error:

private final @Named("remoteSessionFactoryA) Provider<Session> remoteSessionFactory;

Please suggest how to resolve this.

Regards

Upvotes: 2

Views: 9542

Answers (1)

saw303
saw303

Reputation: 9072

The Named annotation should be part of the constructor argument. Since let Lombok generating the constructor there is no way to set the @Named annotation by Lombok.

I recommend to write the constructor yourself such as:

@Context
@Slf4j
public class RemoteService {
   private final Provider<Session> remoteSessionFactory;

   public RemoteService(@Named("remoteSessionFactoryA") Provider<Session> remoteSessionFactory) {
       this.remoteSessionFactory = remoteSessionFactory;
   }
}

Micronaut can’t inject the bean because the name doesn’t match the naming convention. The Micronaut document states:

Micronaut is capable of injecting V8Engine in the previous example, because: @Named qualifier value (v8) + type being injected simple name (Engine) == (case-insensitive) == The simple name of a bean of type Engine (V8Engine) You can also declare @Named at the class level of a bean to explicitly define the name of the bean.

So if you put the names on the source beans Micronaut will pick up the name you defined.

@Slf4j
@Prototype
@AllArgsConstructor
@Named("remoteSessionFactoryA") 
public class RemoteSessionFactoryA implements Provider<Session> {
    //some code here
}

@Slf4j
@Prototype
@AllArgsConstructor
@Named("remoteSessionFactoryB") 
public class RemoteSessionFactoryB implements Provider<Session> {
    //some code here
}

Alternatively create qualifier annotations.

@Qualifier
@Retention(RUNTIME)
public @interface FactoryA {
}

@Qualifier
@Retention(RUNTIME)
public @interface FactoryB {
}

and then inject it like this

@Context
@Slf4j
public class RemoteService {
   private final Provider<Session> remoteSessionFactory;

   public RemoteService(@FactoryA Provider<Session> remoteSessionFactory) {
       this.remoteSessionFactory = remoteSessionFactory;
   }
}

Upvotes: 2

Related Questions