Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoUniqueBeanDefinitionException: no qualifying bean of type. I defined, expected a single matching bean, but I found 2

We've been searching around a bit on both the internet and our paperback courses but can't seem to find a solution to our problem:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [services.GebruikerDAO] is defined: expected single matching bean but found 2: gebruikerDAO,GebruikerDAO
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:863)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 58 more

To sketch some background information: we have to make a small website using java jsp pages and all, together with spring security and maven using a DB to get information and check for information. Following will be all our files.

This is our GebruikerDAO class:

package services;
import domein.Gebruiker;

public interface GebruikerDAO extends GenericDao<Gebruiker>{

    public Gebruiker getGebruikerByStamnummer(String stamnummer);

}

This is our JpaGebruikerDao class:

@Repository("gebruikerDAO")
public class JpaGebruikerDao extends GenericDaoJpa<Gebruiker> implements GebruikerDAO{

    @PersistenceContext
    private EntityManager em;

    public JpaGebruikerDao()
    {
        super(Gebruiker.class);
    }

    /*@Override
    @Transactional
    public List<Gebruiker> findAll() {
        CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        CriteriaQuery<Gebruiker> criteriaQuery = criteriaBuilder.createQuery(Gebruiker.class);

        Root<Gebruiker> gebruiker = criteriaQuery.from(Gebruiker.class);

        criteriaQuery.orderBy(criteriaBuilder.desc(gebruiker.get(Gebruiker_.familienaam)));

    // JPQL select 
        criteriaQuery.select(gebruiker);

        TypedQuery<Gebruiker> query = em.createQuery(criteriaQuery);
        return query.getResultList();
    }*/

    // CRUD methods
    @Override
    @Transactional
    public Gebruiker update(Gebruiker gebruiker) {
        return em.merge(gebruiker);
    }

    @Override
    @Transactional(readOnly = true)
    public Gebruiker get(String id) {
        return em.find(Gebruiker.class, id);
    }

    @Override
    @Transactional
    public void insert(Gebruiker gebruiker) {
        em.persist(gebruiker);
    }

    @Override
    @Transactional
    public void delete(Gebruiker gebruiker) {
        em.remove(em.merge(gebruiker));
    }

    @Override
    public Gebruiker getGebruikerByStamnummer(String stamnummer) {
        return get(stamnummer);
    }
}

This is our Controller class:

@Controller
public class PlanningController {

    @Autowired
    @Qualifier("GebruikerDAO")
    private GebruikerDAO gebruikerDao;

    @RequestMapping(value = "/planning", method = RequestMethod.GET)
    public String listGuest(Model model)
    {
        List<Gebruiker> gebruikerlijst = gebruikerDao.findAll();
        List<Student> studentlijst = new ArrayList<>();

        for (Gebruiker s : gebruikerlijst) {
            if (s instanceof Student){
                Student student = (Student)s;
                if(student.getLokaal() != null)
                {
                    studentlijst.add(student);
                }
            }
        }
        // there is more but it just checks for if a timeslot is available in our planning

This is our spring-security file:

<beans:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:beans="http://www.springframework.org/schema/beans"
         xmlns:p="http://www.springframework.org/schema/p"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

<beans:import resource="applicationContext.xml"/>

<http auto-config="true">
    <intercept-url pattern="/admin*" access="hasAnyRole('ROLE_Student', 'ROLE_Promotor', 'ROLE_Coordinator')"/>
    <logout logout-success-url="/planning.htm"/>
    <access-denied-handler ref="accessDeniedHandler"/>
    <remember-me/>
</http>

<authentication-manager>
    <authentication-provider>
        <password-encoder hash="sha-256"/>
        <jdbc-user-service data-source-ref="dataSource"
                           users-by-username-query="select StamNummer, WachtwoordEncrypted, 'true' as enabled from gebruiker where StamNummer=?"
                           authorities-by-username-query="select StamNummer, Type as authority from gebruiker where StamNummer=?"
                           role-prefix="ROLE_"
        />
    </authentication-provider>
</authentication-manager>

<beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>

This is our applicationContext file:

<?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:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <bean name = "GebruikerDAO" class="services.JpaGebruikerDao"/>
</beans>

This is our dispatcher-servlet file:

<?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:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:jee="http://www.springframework.org/schema/jee"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">   

<mvc:annotation-driven />
<context:component-scan base-package="controller"/>
<context:component-scan base-package="services"/>

<bean id="accessDeniedHandler" class="handler.MyAccessDeniedHandler">
    <property name="accessDeniedUrl" value="403"/>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/bachelorproef"/> <!--  jdbc:mysql://localhost:3306/mysql?zeroDateTimeBehavior=convertToNull-->
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>domein</value>
        </list>
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" /> 
            <property name="generateDdl" value="true" />
            <property name="database" value="MYSQL"/>
        </bean>
    </property>
</bean>

<bean id="transactionManager" 
      class=" org.springframework.orm.jpa.JpaTransactionManager ">
    <constructor-arg ref="entityManagerFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/"
      p:suffix=".jsp" />
</beans>

This is our web.xml file:

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-   app_2_4.xsd">
<display-name>Spring MVC Application</display-name> 
<servlet>
    <servlet-name>dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/dispatcher-servlet.xml, 
                            /WEB-INF/spring-security2.xml
    </param-value> 
</context-param> 
<filter>
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping>
</web-app>

This is our Gebruiker class:

@Entity
@Table(name = "gebruiker")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "Type")
public abstract class Gebruiker implements Serializable {

@Id
@Column(name = "StamNummer")
private String stamNummer;
@Column(name = "Familienaam")
private String familienaam;
@Column(name = "Voornaam")
private String voornaam;
@Column(name = "Email")
private String email;
@Column(name = "Wachtwoord")
private String wachtwoord;
@Column(name = "Campus")
private String campus;
@Transient
private String naam;

public Gebruiker() {

}
(+ some extra getters, setters and generatePassword methods)

This is our Student class:

@Entity
@DiscriminatorValue("Student")
public class Student extends Gebruiker{

@ManyToOne
private Promotor promotor;

@OneToOne
@JoinColumn(name = "HuidigDossier_DossierId")
private Dossier dossier;

@Temporal(TemporalType.TIMESTAMP)
private Date datumPresentatie;  

private String lokaal;
(+ some getters, setters and toString)

This is our Promotor class:

@Entity
@DiscriminatorValue("Promotor")
public class Promotor extends Gebruiker {

    @OneToMany(mappedBy="promotor")
    List<Student> studenten;

    public Promotor(){
         studenten = new ArrayList<>();
    }

    public List<Student> getStudenten() {
        return studenten;
    }

    public void setStudenten(List<Student> studenten) {
        this.studenten = studenten;
    }

}

This is our BPCoordinator class:

@Entity
@DiscriminatorValue("Coordinator")
public class BPCoordinator extends Gebruiker{

    public BPCoordinator(){

    }
}

I know there is lots of information to be found if the NoUniqueBeanDefinitionException error occurs, but this almost always refers to the entityManager, here he says both gebruikerDAO and GebruikerDAO or something are found and we have no idea where he gets them from or why this error occurs. Most of this code has been almost purely copy paste from other schoolprojects and paperbackcode (our course given by to us by our lectors)

Ideas where and how to fix the issue would be amazing.

like image 460
Tempuslight Avatar asked May 19 '14 17:05

Tempuslight


People also ask

Can we have multiple beans of a same type in a class?

2. Using Java Configuration. This is the simplest and easiest way to create multiple beans of the same class using annotations. In this approach, we'll use a Java-based configuration class to configure multiple beans of the same class.

What is the use of @qualifier and @primary?

It's worth noting that if both the @Qualifier and @Primary annotations are present, then the @Qualifier annotation will have precedence. Basically, @Primary defines a default, while @Qualifier is very specific.

What is @primary annotation in Spring boot?

Annotation Type PrimaryIndicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.


1 Answers

There are two possible solutions for this exception. 1- Either define the class only in the XML file and use @Qualifier:

public class PlanningController {

@Autowired
@Qualifier("GebruikerDAO")
private GebruikerDAO gebruikerDao;

In XML define a bean for PlanningController only

2- Or remove Qualifier annotation, and add getters and setters or constructor in PlanningController then in the XML define the context with the property:

<bean class="[path of PlanningController]">
<property name="gebruikerDao" ref="[GebruikerDAO implementation bean name]"/>

like image 116
user666 Avatar answered Sep 20 '22 19:09

user666