1

I've tried everything i can think of to fix this error but spring cannot seem to differentiate between the base holdService and it's child activationHoldService.

@Component("ActivationHoldService")
public class ActivationHoldServiceImpl extends HoldServiceImpl {

@Component("BaseHoldService")
public class HoldServiceImpl implements HoldService {

@Component("com.erac.vos.webservice.hold.HoldWebServiceValidator")
public class HoldWebServiceValidator extends BaseValidator {
  private static final Log LOG = LogFactory.getLog(
      com.erac.vos.webservice.hold.HoldWebServiceValidator.class);
  @Autowired
  @Qualifier("BaseHoldService")
  private HoldService holdService;

I'm trying to Autowire the HoldService but i keep getting the error message

could not autowire field: private com.erac.vos.service.vehicle.hold.HoldService com.erac.vos.webservice.vehicle.hold.HoldWebServiceValidator.holdService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.erac.vos.service.vehicle.hold.HoldService] is defined: expected single matching bean but found 2: [ActivationHoldService, BaseHoldService]

I've tried changing it to

@Resource(name="BaseHoldService",type=com.erac.vos.service.vehicle.hold.HoldServiceImpl.class)

Including excluding the quailifier and even switching the baseHoldService to a different name, and any combination of those things i can think of, to get it to work but it still cant find it. the strangest part is have a near identical line of code in a different class that works perfectly fine

@Resource(name="BaseHoldService",type=com.erac.vos.service.vehicle.hold.HoldServiceImpl.class)
  private HoldService defaultHoldService;

Any Ideas whats going on?

  • 1
    What version of Spring are you using? On newer versions, change `@Autowired` with `@Inject`, and `@Qualifier` with `@Named`. – Tobb Mar 17 '14 at 21:52
  • Show us your context configuration. – Sotirios Delimanolis Mar 17 '14 at 22:04
  • 1
    @tobb Why? You just switch the Spring version for their JEE counterparts. – Bart Mar 17 '14 at 22:24
  • Both methods you've described are perfectly fine ways of doing it. Something else is interfering. We won't know until you show us more. – Sotirios Delimanolis Mar 17 '14 at 23:03
  • Not saying it will solve this problem, it's just the proper way to do it, since it allows you to change DI-framework with a lot less hazzle. If you use a version of Spring that supports it, use the JEE annotations! This problem I would assume is related to the inheritance between beans, I'm not sure if it's supported, and I'm very sure that it's a bad idea. The proper way to do it would be to have multiple implementations of the same interface, if you need common logic then create an abstract class that is not `@Component`-annotated. – Tobb Mar 18 '14 at 07:30

2 Answers2

2

There is the Primary annotation of spring which can help you solve the problem "easily", but i dont think this is what you are looking for.

The Qualifier annotation should do the job as far as i can tell, so you have to dig deeper.

There is a method in the DefaultListableBeanFactory called determinePrimaryCandidate which is responsible to resolve duplicates if possible and this is where the exception is thrown.

http://docs.spring.io/spring/docs/3.2.5.RELEASE/javadoc-api/org/springframework/beans/factory/support/DefaultListableBeanFactory.html#determinePrimaryCandidate(java.util.Map,%20org.springframework.beans.factory.config.DependencyDescriptor)

I would debug inside this method and check why your Qualifier is not resolved properly. It could be a simple typo so the match is not done according to your expectation or it's something less trivial, but this should be the right place to dig.

Martin Frey
  • 10,025
  • 4
  • 25
  • 30
  • +1 for `@Primary` suggestion, because in my case that's exactly what I was looking for. For context, I have a dependency injected class in a library, and a subclass in the application. I need a `@Component` annotation on both, and was having trouble instantiating a unique instance. – Huw Walters Jan 16 '19 at 07:05
0

I eventually figured out if i removed the package declaration from the annotation and lowercased the first letter it worked. i still dont understand why this works and it didnt before but it works now