(Resolvido)Vraptor 3, Daos e Spring (não funciona a injeção )

Bom pessoal, percebi que é uma duvida muito comum entre iniciantes igual a mim com o Vraptor
antes que me perguntem (já gogleou?), a resposta é sim, to a 3 dias tentando.
valeu
entao vamos lá…

oque fiz até agora,
criei interfaces para meus daos e meus controllers
criei uma classe abstrata pra cada um com uma implementação padrao

criei aqueles sessionfactory da apostila do vraptor
lá configurei meu hibernate. bem parecido com um tutorial do wbotelhos sobre controle de login.
até ai tudo bem…
se eu colocar no meu construtor do controller o dao o vraptor nao consegue instanciar o (usuarioDao)
se deixar somente o Result ele funciona…

sendo que meu usuarioDao só recebe a session (org.hibernate.session)

e nao funciona…
meu dao esta anotado como @Component
meu controller como Resource
meu bean esta funcionando com o bibernate numa clase teste que fiz(entao o problema nao é ele)

a exception é essa que já vi muitos com o mesmo problema, mas nao to conseguindo resolver…

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usuariosController': Unsatisfied dependency expressed through constructor argument with index 1 of type [com.sentinela.genericos.Dao]: : No matching bean of type [com.sentinela.genericos.Dao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.sentinela.genericos.Dao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
	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.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:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:636)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.sentinela.genericos.Dao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
	... 34 more

alguma ajuda ? Dica que possa estar esquecendo… possivel bug na ultima versão do vraptor? valeuu

Alguma possivel causa por nao estar criando o meu Dao sendo que ele esta anotado como Component e recebe uma session
criei os sesssionfactory, adicionei num SpringProvider…
o vraptor chama eles, adiciona,
o dao sozinho funciona também!!
so o Spring noa consegue inicializar ele!
Ajuda?!?

qual é a hierarquia de classes?

Dao é uma Interface?

se sim vc precisa que uma implementação dele esteja anotada com @Component

o ideal é ter:

@Component
public class UsuarioDao .... {

}

e receber UsuarioDao no controller ou ter:

public interface UsuarioDao {
  //...
}
@Component
public class HibernateUsuarioDao implements UsuarioDao {

}

e receber UsuarioDao (a interface) no controller

Poisé, tenho a seguinte forma

interface Dao {}

abstract class DaoImpl implements Dao{}

@component
class UsuarioDao extends DaoImpl{
   public UsuarioDao(Session session){}
}

@Resource
class UsuarioController{
    public UsuarioController(Result result,UsuarioDao dao){/*construtor*/}
}

Pelos exemlos que vi tinha que funionar assim…
e como falei na primeira postagem, uso as SessionFActory e registrei os provider como a apostila diz pra fazer…

(Sabe aquele problema que vc passa e pensa assim…“Caraca isso já consegui fazer funcionar por que agora não vai”, to nessa!)
Abraços e obrigado pela dica…

estranho, vc tá recebendo UsuarioDao no construtor e tá dando erro que não achou o Dao?

acho que dentre meus testes peguei uma stacktrace errada mas ele não acha o UsuarioDao. não consegue criar passando a session pra ela!

ah tá… vc tem algum componente que cria a Session? ou registrou a configuração de packages com o pacote do hibernate?

tenho meu provider no web.xml

	<context-param>
		<param-name>br.com.caelum.vraptor.provider</param-name>
		<param-value>com.jaja.sistema.hibernate.SentinelaProvider</param-value>
	</context-param>

e minhas outras classes


package com.jaja.sistema.controller;

import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;

import com.jaja.sistema.genericos.GenericControllerImpl;
import com.sentinela.dao.UsuarioDao;
import com.sentinela.model.Usuarios;

@Resource
public class UsuariosController extends GenericControllerImpl<Usuarios> {

	public UsuariosController(Result res, UsuarioDao dao) {
		super(res, dao);
	}
}
}


//meu daoimpl que foi a maneira mais eleante que achei pra fazer
package com.sentinela.genericos;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;

import com.sentinela.Constantes;
import com.sentinela.exception.SentinelaException;

public abstract class DaoImpl<T> implements Dao<T> {

	private final Session session;
	public final Class<T> classe;

	public DaoImpl(Class<T> classe, Session se) {
		this.session = se;
		this.classe = classe;

	}
}

package com.sentinela.dao;

import br.com.caelum.vraptor.ioc.Component;

import com.sentinela.genericos.DaoImpl;
import com.sentinela.model.Usuarios;

@Component
public class UsuarioDao extends DaoImpl<Usuarios> {

	public UsuarioDao(org.hibernate.Session session) {
		super(Usuarios.class, session);
	}

}

public interface Dao<T> {}

meu provider com spring

public class SentinelaProvider extends SpringProvider {

	@Override
	protected void registerCustomComponents(ComponentRegistry registry) {
		registry.register(SentinelaSessionCreator.class,
				SentinelaSessionCreator.class);
		registry.register(SentinelaSessionFactoryCreator.class,
				SentinelaSessionFactoryCreator.class);
		registry.register(HibernateTransactionInterceptor.class,
				HibernateTransactionInterceptor.class);
	}

}

sessioncreator



@Component
@RequestScoped
public class SentinelaSessionCreator implements ComponentFactory<Session> {

	private final SessionFactory factory;
	private Session session;

	public SentinelaSessionCreator(SessionFactory factory) {
		this.factory = factory;
	}

	@PostConstruct
	public void create() {
		this.session = factory.openSession();
	}

	public Session getInstance() {
		return session;
	}

	@PreDestroy
	public void destroy() {
		this.session.close();
	}

}




//e a ultima


@Component
@ApplicationScoped
public class SentinelaSessionFactoryCreator implements
		ComponentFactory<SessionFactory> {

	private SessionFactory factory;

	@PostConstruct
	public void create() {
		AnnotationConfiguration configuration = new AnnotationConfiguration();
		configuration.setProperty("hibernate.connection.username", "login");
		configuration.setProperty("hibernate.connection.password", "senha");
		configuration.setProperty("hibernate.connection.url",
				"jdbc:postgresql://localhost:5432/banco");
		configuration.setProperty("hibernate.connection.driver_class",
				"org.postgresql.Driver");
		configuration.setProperty("hibernate.dialect",
				"org.hibernate.dialect.PostgreSQLDialect");
		configuration.setProperty("show_sql", "true");
		configuration.setProperty("format_sql", "true");
		configuration.addPackage("com.sentinela.model");
		configuration.addAnnotatedClass(Usuarios.class);

		factory = configuration.buildSessionFactory();

	}

	public SessionFactory getInstance() {
		return factory;
	}

	@PreDestroy
	public void destroy() {
		factory.close();
	}

}

vc não precisa do seu SEntinelaProvider… só as anotações @Component são suficientes…

qual é o erro que está acontencendo? posta a stack aqui

agora to sem meus fontes aqui no trabalho, quando chegar em casa posto aqui, e por enquanto obrigado pela ajuda!


org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usuariosController': Unsatisfied dependency expressed through constructor argument with index 1 of type [com.sentinela.dao.UsuarioDao]: : No matching bean of type [com.sentinela.dao.UsuarioDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.sentinela.dao.UsuarioDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
	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.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	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.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:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:636)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.sentinela.dao.UsuarioDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
	... 42 more

a classe UsuarioDao está dentro de um jar? ou está compilada com o resto da aplicação?

pq se ela está anotada com @Component não deveria dar esse erro

Poisé meu amigo, ai esta meu dilema…
esta junto com a aplicação…
se retiro o UsuarioDao do construtor
o spring injeta certinho e chama meu index de UsuarioController.
me diz a versão dos teus jars do spring pra mim conferir.
to achando que pode ser isso!
abraços!

se quiser de mando meus projetos por e-mail

não é versão do spring… se o UsuarioDao está mesmo anotado com @Component do VRaptor deveria funcionar recebê-lo no construtor do controller…

tenta dar um clean no projeto e no servidor só pra garantir

Poisé amigo, peguei o vraptor-blank do site da caelum
copiei meus fontes lá pra dentro.
rodou bunitinho, dai fui chamar meu controller de usuarios
advinha
nao funcionou!

cara, tem algo a ver com o fato de eu ter meu controller no projeto web e meu UsuarioDao num java-project que é usado no projeto web…
dai coloco nas dependencias do projeto e tals…
pode ser por isso que ele não encontre meu UsuarioDao…
teria de ter elejunto com o projeto web?

ah tah… se o UsuarioDao está em outro projeto, vc precisa registrar o pacote dele no web.xml…

o VRaptor só escaneia por padrão o que está em WEB-INF/classes.

coloque essa configuração:

<context-param>
    <param-name>br.com.caelum.vraptor.packages</param-name>
    <param-value>br.com.pacote.do.dao</param-value>
</context-param>

se esse projeto externo tiver mais pacotes com componentes, vc precisa registrar todos (separados por vírgula) ou registrar um pacote pai deles.

GRANDE LUCAS…
SIMPLES ASSIM…
hehe
obrigado pela ajuda

ultima duvida…
depois é so programar e esquecer de problemas
Para funcionar com meus models obrigatoriamente preciso fazer isso?

<context-param>  
    <param-name>br.com.caelum.vraptor.packages</param-name>  
    <param-value>
br.com.pacote.do.dao,pacotecommeusMODELS</param-value>  
</context-param>  

pois meus beans que o hibernate usa também estão em outro projeto!

vc só precisa fazer isso se algum dos seus models é um @Component, @Resource, @QQerCoisaDoVRaptor