Vraptor + hibernatetools

Boa tarde pessoal,

Estou iniciando meus estudos no Vraptor , mas estou utilizando a classe de persistencia gerada pelo hibernate tools , pois meu projeto utilizará esse plugin pra geração dos DAOS e Entidades…

estou tendo um problema em utilizar o vraptor chamando uma simples listagem no banco de dados…

classe gerada pelo Hibernate Tools :

public class ProdutoHome {

	private static final Log log = LogFactory.getLog(ProdutoHome.class);

	private final SessionFactory sessionFactory = getSessionFactory();
    	
	public ProdutoHome (){

	}
	
	protected SessionFactory getSessionFactory() {
		try {
			
			return (SessionFactory) new InitialContext()
					.lookup("SessionFactory");
		} catch (Exception e) {
			log.error("Could not locate SessionFactory in JNDI", e);
			throw new IllegalStateException(
					"Could not locate SessionFactory in JNDI");
		}
	}

	public void persist(Produto transientInstance) {
		log.debug("persisting Produto instance");
		try {
			sessionFactory.getCurrentSession().persist(transientInstance);
			log.debug("persist successful");
		} catch (RuntimeException re) {
			log.error("persist failed", re);
			throw re;
		}
	}

	public void attachDirty(Produto instance) {
		log.debug("attaching dirty Produto instance");
		try {
			sessionFactory.getCurrentSession().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(Produto instance) {
		log.debug("attaching clean Produto instance");
		try {
			sessionFactory.getCurrentSession().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void delete(Produto persistentInstance) {
		log.debug("deleting Produto instance");
		try {
			sessionFactory.getCurrentSession().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public Produto merge(Produto detachedInstance) {
		log.debug("merging Produto instance");
		try {
			Produto result = (Produto) sessionFactory.getCurrentSession()
					.merge(detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public Produto findById(int id) {
		log.debug("getting Produto instance with id: " + id);
		try {
			Produto instance = (Produto) sessionFactory.getCurrentSession()
					.get("classes.Produto", id);
			if (instance == null) {
				log.debug("get successful, no instance found");
			} else {
				log.debug("get successful, instance found");
			}
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public List findByExample(Produto instance) {
		log.debug("finding Produto instance by example");
		try {
			List results = sessionFactory.getCurrentSession()
					.createCriteria("classes.Produto")
					.add(Example.create(instance)).list();
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}
	
	public List<Produto> listaTudo() {
		return sessionFactory.getCurrentSession().createCriteria("classes.Produto").list();
	}
}

Erro encontrado ao chamar o metodo listaTudo() pelo controller do vraptor :

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘produtosController’: Unsatisfied dependency expressed through constructor argument with index 0 of type [classes.ProdutoHome]: : Error creating bean with name ‘produtoHome’: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [classes.ProdutoHome]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Could not locate SessionFactory in JNDI; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘produtoHome’: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [classes.ProdutoHome]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Could not locate SessionFactory in JNDI
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:43)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:263)
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:86)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:46)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88

já tentei colocar essas 2 linhas no hibernate.cfg , mas sem sucesso…

<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
 <property name="hibernate.current_session_context_class">thread</property>

se eu fizer meu getSessionFactory assim :

	protected SessionFactory getSessionFactory() {
		try {
			Configuration cfg = new Configuration();
			cfg.configure();
			SessionFactory sf = cfg.buildSessionFactory();

		} catch (Exception e) {
			log.error("Could not locate SessionFactory in JNDI", e);
			throw new IllegalStateException(
					"Could not locate SessionFactory in JNDI");
		}
	}

eu recebo essa exceção :

br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: org.hibernate.HibernateException: createCriteria is not valid without active transaction

Alguém sabe como proceder nesse caso ?

Desdej á grato pela ajuda… :smiley:

se em vez de usar o getSessionFactory gerado pelo hibernate tools, eu estou usando esse método :

	protected Session getSession() {
		try {
			 AnnotationConfiguration configuration = new AnnotationConfiguration();
			 configuration.configure();
			
			 SessionFactory factory = configuration.buildSessionFactory();
			 Session session = factory.openSession();
			 
			 return session;
			
		} catch (Exception e) {
			log.error("erro renan", e);
			throw new IllegalStateException(
					"Could not locate Renan");
		}
	}

eu não tenho problemas, mas gostaria de utilizar o código gerado pelo hibernate tools, pois seria bem mais produtivo… alguém poderia me ajudar ?? :slight_smile:

Não faça isso! a session factory só deveria ser criada uma vez em todo o sistema! não toda hora que vc precisa de uma session…

jeito fácil de fazer no vraptor:

receba uma Session no construtor, e registre o pacote do hibernate no web.xml:
http://vraptor.caelum.com.br/pt/docs/componentes-utilitarios-opcionais/
(seção Hibernate session e sessionFactory)

[quote=Lucas Cavalcanti]Não faça isso! a session factory só deveria ser criada uma vez em todo o sistema! não toda hora que vc precisa de uma session…

jeito fácil de fazer no vraptor:

receba uma Session no construtor, e registre o pacote do hibernate no web.xml:
http://vraptor.caelum.com.br/pt/docs/componentes-utilitarios-opcionais/
(seção Hibernate session e sessionFactory)[/quote]

Lucas, obrigado pela dica…

eu só fiz isso pra continuar estudando o vraptor , nunca pensei em colocar em produção , estava esperando um retorno , rsrsrs!!!

como eu faria ? colocaria uma Session ou SessionFactory no construtor? e no construtor de onde ? do DAO ? no caso seria no construtor da classe ProdutoHome ?

e colocaria isso no xml ?

<context-param>
    <param-name>br.com.caelum.vraptor.packages</param-name>
    <param-value>
        br.com.caelum.vraptor.util.outros.pacotes...,
        br.com.caelum.vraptor.util.hibernate
    </param-value>
</context-param>

vlws cara!!!

sem a linha dos outros pacotes :wink:

vc recebe a Session no construtor do DAO (que é um @Component) e usa essa session.

Dá uma olhada na apostila do VRaptor, que ela explica direitinho:

http://www.caelum.com.br/apostilas/#FJ-28

[quote=Lucas Cavalcanti]sem a linha dos outros pacotes :wink:

vc recebe a Session no construtor do DAO (que é um @Component) e usa essa session.

Dá uma olhada na apostila do VRaptor, que ela explica direitinho:

http://www.caelum.com.br/apostilas/#FJ-28[/quote]

lucas , muito obrigado… quando eu tiver um tempo vou testar e posto o feedback…

essa forma só funciona se a entidade estiver anotada com as coisas do hibernate? pq eu uso xml… e funciona com o SessionFactory tranquilo também ?

funciona com xml tb.