springgenericdao

GenericDAO and NoSuchBeanDefinitionException: No unique bean Spring 3.0


I'm using Spring 3.0 with a genericDAO. I have this:

public interface GenericDAO<T, ID extends Serializable>
...
@Repository("genericDAO")
public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {
...
public interface A extends GenericDAO<Turno, Long> {
...
public interface B extends GenericDAO<TipoTurno, Long> {
...
@Repository("A")
public class AImpl extends GenericDAOImpl<TipoTurno, Long>  implements A{
...
@Repository("B")
public class BImpl extends GenericDAOImpl<TipoTurno, Long>  implements B{

But when I try to get them injected as follow:

@Autowired
A a;

I get:

expected single matching bean but found 3: [genericDAOImpl, A, B]

I can't understand why. I also tried to do it with

@Resource(name="A")

and even

@Resource(type=A.class)

I also tried using @Qualifier but I always get the same exceptions, it looks like Spring is always looking for GenericDao and not the specific class.

but it's still not working. And I can't understand why.

Any suggestions?

Thank you very much.


Solution

  • I reproduced your exact error message and then fixed it. Here is exactly the source code I used, minus package names. I recommend copying it, running it and diffing it with yours. One difference I noticed is that as written in the question, AImpl does not compile. It implements both GenericDAOImpl and GenericDAO. I changed the first generic parameter to Turno, to make it compile. I assume this was a typo. I reproduced exactly your error when I initially set all the fields to @Autowired. Then I added @Qualifier("genericDAO") and it wired all three successfully.

    public interface GenericDAO<T, ID extends Serializable> {}
    ...
    @Repository("genericDAO")
    public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {}
    ...
    public interface A extends GenericDAO<Turno, Long> {}
    ...
    public interface B extends GenericDAO<TipoTurno, Long> {}
    ...
    @Repository("A")
    public class AImpl extends GenericDAOImpl<Turno, Long> implements A {}
    ...
    @Repository("B")
    public class BImpl extends GenericDAOImpl<TipoTurno, Long>  implements B {}
    ...
    public class TipoTurno {}
    ...
    public class Turno {}
    ...
    @Component
    public class Thingy {
        @Autowired
        private A a;
    
        @Autowired
        private B b;
    
        @Autowired
        @Qualifier(value="genericDAO")
        private GenericDAO genericDao;
    }
    ...
    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("genericdao.xml");
            context.getBean(Thingy.class);
        }
    }
    ...
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <context:annotation-config/>
        <context:component-scan base-package="genericdao"/>
    </beans>
    

    Note that the actual error message is longer than the one you provided. It is important to read the whole thing looking for causes. Spring loves exception stack traces with 5, even 10 levels of causes. Here is the relevant substring of the message I get:

    Could not autowire field: genericdao.GenericDAO genericdao.Thingy.genericDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [genericdao.GenericDAO] is defined: expected single matching bean but found 3: [A, B, genericDAO]

    It indicates that the field that was not being autowired was Thingy.genericDao, not Thingy.a. I strongly suspect this is the case for your error as well.