2

I am working with SpringMVC+Hibernate, I want to apply Inheritance in DAO layer, I am doing like below:

BaseDao.java

public interface BaseDao
{
   public Serializable save(Object object) throws DataAccessException,
        HibernateException;

public void merge(Object object) throws DataAccessException,
        HibernateException;

public void flush() throws DataAccessException,HibernateException;
 }

EmpDao.java

 public interface EmpDao extends BaseDao{
 }

BaseDaoImpl.java

@Repository
public class BaseDaoImpl implements BaseDao{
 // Implementation for baseDao methods 
}

EmpDaoImpl .java

 @Repository
public class EmpDaoImpl extends BaseDaoImpl implements EmpDao{
 // Implementation
}

But I am getting below error:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 
[BaseDao] is defined: expected single matching bean but found 2

What am I missing here?

Bohuslav Burghardt
  • 33,626
  • 7
  • 114
  • 109
Soujanya
  • 277
  • 4
  • 17
  • Can you show entire stacktrace? – IlGala Nov 12 '15 at 10:53
  • 1
    Do you really need instance of `BaseDaoImpl` as a standalone bean? If not, just remove the `@Repository` annotation from it and mark the `BaseDaoImpl` class as `abstract` (optional, but good practice). It will then be enough to have `@Repository` annotation on concrete Dao implementations (e.g. `EmpDaoImpl`). – Bohuslav Burghardt Nov 12 '15 at 11:05
  • Dont you think you need @Qualifier? – dharam Nov 12 '15 at 11:12
  • @Soujanya you are using spring data, why don't you use `JpaRepository` interface instead and if you need to customize it - you can extend `SimpleJpaRepository` class, if you don't need to customize ( add new methods ) - then you don't need the implementation class, an interface with `@Repository` annotation is enough, Spring creates the class in runtime – Zilvinas Nov 12 '15 at 16:46

4 Answers4

1

If you really want to have both BaseDaoImpl and EmpDaoImpl as two beans in your Spring container, you need to tell Spring which one to use wherever you have an @Autowired field of type BaseDao using @Qualifier annotation.

Related: Understanding Spring @Autowired usage

Community
  • 1
  • 1
Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
1

It seems like you're trying to inject BaseDao and Spring is complaining there are two candidates.

I think this is actually a design problem. You wanted to use BaseDaoImpl both as a concrete bean that you use directly and also as a base class for other DAOs. This is bad because the sub-classes does not actually extend but simply uses their parent class. The better pattern would be to get rid of the extends and simply inject the BaseDaoImpl into the other DAOs.

Also, the interfaces looks superfluous. If you're working around the proxy problem, just use proxyTargetClass.

billc.cn
  • 7,187
  • 3
  • 39
  • 79
1

You can use generic types like this

BaseDao.java

public interface BaseDao<EntityType extends Object>
{
   public Serializable save(EntityType entity) throws DataAccessException,
        HibernateException;

   public void merge(EntityType entity) throws DataAccessException,
        HibernateException;

   public void flush() throws DataAccessException,HibernateException;
}

BaseDaoImpl.java

@Repository
public abstract class BaseDaoImpl<EntityType extends Object> implements BaseDao<EntityType>{
 // Implementation for baseDao methods 
}

EmpDao.java

 public interface EmpDao extends BaseDao<Employee>{
 }

EmpDaoImpl .java

 @Repository
public class EmpDaoImpl extends BaseDaoImpl<Employee> implements EmpDao{
 // Implementation
}
Oskar Dajnowicz
  • 1,700
  • 12
  • 16
0

You need to add the @NoRepositoryBean on the BaseDao interface so spring would not create a bean for it, as well as for EmpDao I assume

Zilvinas
  • 5,518
  • 3
  • 26
  • 26
  • `@NoRepositoryBean` is a Spring Data annotation. I don't see any indication in the question that OP uses Spring Data, so it would probably be of no use here. – Bohuslav Burghardt Nov 12 '15 at 11:03
  • As well as `@Repository` bean is from Spring Data, which is being used. On the other hand - `@Qualifier` always helps to specify the exact bean name. – Zilvinas Nov 12 '15 at 16:43
  • `@Repository` is not from Spring Data. It is a core stereotype annotation included for instance in `spring-context` dependency. – Bohuslav Burghardt Nov 12 '15 at 17:15