2

Hello everyone I'm getting an exception while develeping a web application with spring mvc and hibernate, the problem is that spring don't know my beans Controller

@Autowired
public PersonneMetierImpl personneMetier;

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(Locale locale, Model model) {
    personneMetier.ajouterPersonne(new Personne("azrou", "zakaria.bariki@gmail.com", "bariki", "zakaria", "0641057217"));
    return "test";
}

DAO classe

@Repository
public class PersonneDaoImpl implements IPersonneDao {

@Autowired
private SessionFactory sessionFactory;

@Override
public void ajouterPersonne(Personne personne) {
    if(sessionFactory == null)
        System.out.println("aaaa");
    try{
        sessionFactory.getCurrentSession().save(personne);

    }catch(Exception e){
        e.printStackTrace();
    }
}

Service class Service public class PersonneMetierImpl implements IPersonneMetier{ @Autowired private PersonneDaoImpl personneDao;

@Override
@Transactional
public void ajouterPersonne(Personne personne) {
    personneDao.ajouterPersonne(personne);  
}

Servlet-Context file

    <beans:bean id="datasource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <beans:property name="url"
        value="jdbc:mysql://localhost:3306/gestion_bp" />
    <beans:property name="username" value="root" />
    <beans:property name="password" value="" />
</beans:bean>
<beans:bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <beans:property name="dataSource" ref="datasource" />
    <beans:property name="hibernateProperties">
        <beans:props>
            <beans:prop key="hibernate.show_sql">true</beans:prop>
            <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
            <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
            </beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>


<context:component-scan base-package="com.sqli.bap" />
<beans:bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<beans:bean id="personneDao" class="com.sqli.bap.daoImpl.PersonneDaoImpl"/> 
<beans:bean id="personneMetier" class="com.sqli.bap.metierImpl.PersonneMetierImpl"/> 

Exception

ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.sqli.bap.metierImpl.PersonneMetierImpl com.sqli.bap.HomeController.personneMetier; nested exception is java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5253)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5543)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.sqli.bap.metierImpl.PersonneMetierImpl com.sqli.bap.HomeController.personneMetier; nested exception is java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 29 more
Caused by: java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
    at java.lang.reflect.Field.set(Unknown Source)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:510)
    ... 31 more

Can anyone tell me what's can I do to resolve the problem please Thank you a lot

Aeseir
  • 7,754
  • 10
  • 58
  • 107
user0321
  • 113
  • 1
  • 10

3 Answers3

4

You need to change your controller - replace the line

public PersonneMetierImpl personneMetier;

with

public IPersonneMetier personneMetier;

(that is, use interface instead of an implementation).

In some cases (including yours) Spring doesn't use a bean (PersonneMetierImpl) as-is, but wraps it in a proxy. In this case it is a JDK dynamic proxy, which cannot be cast to PersonneMetierImpl, but only to IPersonneMetier (JDK proxies are interface-based). And that is the reason why Spring cannot autowire field PersonneMetierImpl personneMetier.

Oh, and for the same reason (and also because that's what interfaces are for) you should change PersonneMetierImpl class - replace private PersonneDaoImpl personneDao with private IPersonneDao personneDao.

Roman
  • 6,486
  • 2
  • 23
  • 41
  • just a note: Spring does not create proxy because "a bean implements one more more interfaces". Proxies are created for other purpose, AOP being one of the most common reasons (there are other) – Adrian Shum Nov 19 '15 at 01:25
  • @AdrianShum Yes, that probably was my bad choice of words. What I meant to say, "in some cases" Spring wants to create a proxy. And it prefers to create a JDK proxy, but it can do it _only if_ that bean implements one or more interfaces; otherwise it creates a CGLIB proxy. And a side note: one can instruct Spring to create CGLIB proxies by default ( [Proxying mechanisms](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-proxying) ). – Roman Nov 19 '15 at 02:02
  • 1
    ahha, got what you mean :) I think the sentence can be mis-interpreted in a different meaning. Will be good to adjust your answer accordingly to your comment :) – Adrian Shum Nov 19 '15 at 03:04
0

The controller is not a true representation of the class but rather a proxy generated by Spring. This will implement all the interfaces of the class however so you could use

@Autowired
public IPersonneDao personneMetier;

instead of

@Autowired
public PersonneMetierImpl personneMetier;
Reimeus
  • 158,255
  • 15
  • 216
  • 276
0

This error can also appear as a bug for IntelliJ IDEA users. Eclipse and java for VS Code do not produce this problem.

Subbre
  • 75
  • 3