1

In my application I am using generic DAO pattern. My class structure looks like this:

  1. A domain class - pojo

    package com.test.abc.def;
    @NamedQueries({------a couple of queries go here .......})
    @Entity
    @Table(name = "NAME")
    public class Name implements Serializable {
       private String myName;
       ........
       @Column(name = "MY_NAME", nullable = false, length = 30)
       public String getMyName() {
          return this.myName;
       }
       public void setName(String myName) {
          this.myName= myName;
       }
           ........
    }
    
  2. A DAO interface that corresponds to the NamedQueries in the above Domain class

    package com.test.abc.h;
    public interface INameDao extends IGenericDAO<...., ....> {
     ....method signature......
    }
    
  3. A IGenericDAO interface

    package com.test.abc.h;
    public interface IGenericDAO<T, PK extends Serializable> {
          .........
    }
    
  4. GenericDAO implementation class

    package com.test.abc.h.impl;
    @Repository
    @Scope( BeanDefinition.SCOPE_PROTOTYPE )
    public class GenericDAO<T, PK extends Serializable> implements IGenericDAO<T, PK> {
         ....method implemnetations ........
    }
    
  5. application context:

    <context:component-scan base-package="com.test.abc" />
    <context:annotation-config />
    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    
  6. A service class has the following autowire declarations:

     @Autowired
     private Name name;
     @Autowired
     private INameDAO nameDAO;
     ......
     nameDAO.callToNamedQuery() - here I would like to call the named query present in Name class.  
    

I see the below error when I try to startup the server:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No 
qualifying bean of type [com.test.abc.h.INameDAO] found for dependency: expected at 
least 1 bean which qualifies as autowire candidate for this dependency. Dependency
annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

What am I missing here? I tried adding the @Repository annotation to the INameDAO - and to the Name domain class as well. That did not help. Also added @Component annotation to the Name domain class - that did not help either.

user811433
  • 3,999
  • 13
  • 53
  • 76

2 Answers2

1

your INameDao is interface and INameDao is not implements any class as your code.@Autowired is use for dependency injection and @Autowires not found any INameDao implements class. So you need to first create a Impl class of the INameDao. Your exception is NoSuchBeanDefinitionException so spring not found any qualifying bean of type [com.test.abc.h.INameDAO].

Chirag Kathiriya
  • 427
  • 5
  • 14
0

It looks like your GenericDAO is of type IGenericDAO but you're error suggests you are injecting a bean of type INameDAO. Whilst INameDAO is of type IGenericDAO, your GenericDAO is not of type INameDAO. You need to either fix the inheritance tree of your GenericDAO, or by changing the type of the bean to be injected to include something in it's tree.

EDIT

To provide an example. This is similar to defining java.util.Collection, java.util.List and java.util.Set. You then declare a bean that has a List property and try to inject a Set. Whilst they have a common ancestor, they are incompatible. You could change your bean to accept a Collection property, but you will be restricted to the methods of Collection.

With the structure below you would inject MyActualDAOImpl into a property of type MyActualDAO (I've left off the generics). Put your NamedQueries on yourEntity`.

Public interfaces:

public interface GenericDAO{
    //crud methods
}

public interface MyActualDao inherits GenericDAO{
    //other non-crud methods, if needed
}

Implementation

public abstract class AbstractDAO implements GenericDAO{
    //generic implementations of CRUD
}


public MyActualDAOImpl inherits AbstractDAO implements MyActualDAO{
    ...
}
Romski
  • 1,912
  • 1
  • 12
  • 27
  • the reason I am autowiring INameDAO is to be able to call the named query present in Name domain class. Edited my question to include this info. – user811433 Oct 15 '13 at 00:35
  • Then you need to refactor your code as Spring will try to inject by type and your GenericDAO is not of type INameDAO. With your current definition, you could make your target bean the common type IGenericDAO, but I expect you will lose visibility of other methods in GenericDAO. Either way your current structure won't work. – Romski Oct 15 '13 at 00:42
  • Any suggestions on the specific change that I need to make to correct this? – user811433 Oct 15 '13 at 00:43
  • Updated reply for extra space. – Romski Oct 15 '13 at 04:22
  • thank you for the above example, but I see that here you are adding an Impl for the DAO. Which means adding one more class and moving the NamedQueries as methods into that Impl. Is there no alternative to avoid this? – user811433 Oct 16 '13 at 18:28
  • For myself, I would have an abstract dao for CRUD operations (create, insert, update, delete, find by id). Subclassing, for example a UserDAO adds the typing to the abstract class. Then add user specific operations to the sub class. Any non-generic queries would live on the User entity, eg findUserByEmail – Romski Oct 17 '13 at 07:59