Reputation: 1519
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
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