Problema com Vraptor3.31 + Spring (FJ 28) - Injeção dependências

Pessoal, tou desenvolvendo uma aplicação web e tomei como base a apostila FJ28 para aprender mais sobre o VRAPTOR.

Coloquei o spring pra colocar as transaction, bem até ai tudo bem!

Estava tendo uns problemas com a annotation @Transactional, adicionei o aspectjtools e funcionou essa parte.

Depois disso achei um tópico do Lucas falando que não podia utilizar injeção de dependências, então minha classe DAO ficou assim:


package Model.DAO;

import Model.Beans.Dominio;
import br.com.caelum.vraptor.ioc.Component;
import java.util.List;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author rafaelob
 */

@Component
public class DominioDAO implements DAO {

    private  Session session;

 

    public Session getSession() {
        return session;
    }

    @Autowired
    public void setSession(Session session) {
        this.session = session;
    }


//   
    @Override
    @Transactional
    public boolean salva(Object objeto) {
        try {
            this.session.save(objeto);
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;

        }
    }

  //  @Transactional
    @Override
    public boolean remove(Object objeto) {
        try {
            this.session.delete(objeto);
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;

        }
    }

    @Override
    public Object recupera(Integer id) {
        try {
            return (Dominio) this.session.load(Dominio.class, id);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;

        }
    }

 //   @Transactional
    @Override
    public boolean atualiza(Object objeto) {
        try {
            this.session.update(objeto);
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;

        }

    }

    @Override
    public List<Dominio> recuperaTodos() {
        try {
            return (List<Dominio>) (session.createQuery("From Dominio").list());


        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
}

Meu DominioController


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import Model.Beans.Dominio;
import Model.DAO.DominioDAO;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;

/**
 *
 * @author rafaelob
 */
@Resource
public class DominioController {

    private  DominioDAO dao;
    private final Result result;

    public DominioController( Result result) {
      
        this.result = result;
    }

    public DominioDAO getDao() {
        return dao;
    }
    @Autowired
    public void setDao(DominioDAO dao) {
        this.dao = dao;
    }


    @Path("/dominios")
    @Get
    public List<Dominio> lista() {
        return dao.recuperaTodos();

    }

    @Path("/dominios/novo")
    @Get
    public void formulario() {
    }

    @Path("/dominios")
    @Post
    public void adiciona(Dominio dominio) {
        dao.salva(dominio);  
        result.redirectTo(this.lista());
    }

   
}

Eu recebo essa exception:

AVISO: StandardWrapperValve[default]: PWC1406: Servlet.service() for servlet default threw exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dominioController’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void Controller.DominioController.setDao(Model.DAO.DominioDAO); nested exception is java.lang.IllegalArgumentException: argument type mismatch
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:43)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:263)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:86)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:46)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void Controller.DominioController.setDao(Model.DAO.DominioDAO); nested exception is java.lang.IllegalArgumentException: argument type mismatch
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:589)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
… 53 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:582)
… 55 more

Se eu utilizar o meu controller dessa forma, usando injeção de dependências:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import Model.Beans.Dominio;
import Model.DAO.DominioDAO;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import java.util.List;

/**
 *
 * @author rafaelob
 */
@Resource
public class DominioController {

    private final DominioDAO dao;
    private final Result result;

    public DominioController(DominioDAO dao, Result result) {
        this.dao = dao;
        this.result = result;
    }

    @Path("/dominios")
    @Get
    public List<Dominio> lista() {
        return dao.recuperaTodos();

    }

    @Path("/dominios/novo")
    @Get
    public void formulario() {
    }

    @Path("/dominios")
    @Post
    public void adiciona(Dominio dominio) {
        dao.salva(dominio);  
        result.redirectTo(this.lista());
    }

   
}

Eu tenho essa outra exception:

VISO: StandardWrapperValve[default]: PWC1406: Servlet.service() for servlet default threw exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dominioController’: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [Controller.DominioController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:43)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:263)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:86)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:46)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [Controller.DominioController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:137)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
… 49 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
… 51 more

Grato!

o jeito mais fácil de resolver isso:

  • pode voltar e colocar as dependências no construtor
  • crie uma interface pra cada dao, e receba a interface como dependência do controller (e não a classe concreta).

isso funciona sem problemas

Lucas,

Esses dois passos seriam a forma de resolver o problema? Ou são duas abordagens distintas?

Inicialmente eu recebia no meu construtor do DominioDAO a session, só que com isso eu tinha um problema na hora de injetar a dependência, e lendo um post seu no fórum vi que era para colocar a anotação do spring e colocar set e get. Isso acabou resolvendo para DominioDAO e quebrou para o Controller, que recebia um DominioDAO no construtor.

Aí eu tentei fazer essas duas maneiras acima, e não obtive sucesso.

Se possível gostaria de entender porque esse problema está acontecendo, se você puder dar uma breve explicação para que eu possa procurar mais, eu agradeceria.

é pra vc fazer as duas coisas…

o problema é que qdo vc usa @Transactional (ou qualquer coisa que use AOP), o spring injeta como dependência um proxy, e não a sua classe real.

e se vc não usa interfaces, ele faz o proxy da sua classe chamando o construtor padrão. Se não tiver um construtor padrão ele dá aquela exception.

Se vc programa orientado a interfaces vc não terá esse problema: interfaces são fáceis de proxiar.

resumindo: crie interfaces pros daos e receba as interfaces no construtor das suas classes

Muito obrigado, Lucas!!!

Irei fazer isso! O Construtor padrão que você menciona, é um que não recebe nenhum parâmetro, certo?

Só uma duvadzinha básica:

Anotarei as interfaces com o @Component, certo? Retiro o @Component das implementações das interfaces?

Att,

Obrigado mais uma vez!

o @Component tem que estar nas implementações, não nas interfaces… pode deixar que o VRaptor se vira :wink:

o construtor padrão é o sem argumentos

Muito obrigado,

vou fazer isso agora!

Att,

rafaelob

Bom dia…
Você conseguiu resolver este problema?
Estou tentando implementar o Transaction na minha aplicação, mas estou tendo problemas, você pode me ajudar ?

Abraço…

Edifran, pode ser um pouco mais específico no seu problema?

Boa tarde Lucas…

Meus problemas estão nesse post:
http://www.guj.com.br/java/288660-erro-com-transaction-do-spring-no-vraptor#1536025

Você até já me deu uns helps, mas ainda to perdido :frowning:

Obrigado pela atenção mais uma vez…