GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

CDI com Tomcat e Hibernate

Caros colegas, estou tentando desenvolver uma aplicação com CDI Tomcat e Hibernate, seguindo as dicas de CDI deste artigo http://blog.caelum.com.br/use-cdi-no-seu-proximo-projeto-java

Nesse artigo ele explica como utilizar o Weld com Tomcat, até aí tudo bem, configurei daquela forma subi o Tomcat e não deu nenhum erro, porém no artigo ele mostrar como injetar em um EntityManager mas eu trabalho com o Session do Hibernate. Quando faço a injeção no session ele não me permite dizendo que aquele ponto não serve para injeção.

Alguém sabe como e se é possível usar CDI assim?

[code]public class HibernateUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();


private static SessionFactory buildSessionFactory() {
	try {
		Configuration cfg = new Configuration().configure();
		return cfg.buildSessionFactory();			
	} catch (Throwable e) {
		System.out.println("Criação da SessionFactory falou. Erro: " + e);
		throw new ExceptionInInitializerError(e);
	}
}	

public static SessionFactory getSessionFactory() {
	return sessionFactory;
}

}[/code]

[code]public class HibernateFilter implements Filter {

private SessionFactory sf;


public void init(FilterConfig config) throws ServletException {
	this.sf = HibernateUtil.getSessionFactory();		
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
		FilterChain chain) throws ServletException {
	try {
		this.sf.getCurrentSession().beginTransaction();
		chain.doFilter(servletRequest, servletResponse);
		this.sf.getCurrentSession().getTransaction().commit();
		this.sf.getCurrentSession().close();
	} catch (Throwable ex) {
		try {
			if (this.sf.getCurrentSession().getTransaction().isActive()) {
				this.sf.getCurrentSession().getTransaction().rollback();
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
	  throw new ServletException(ex);	
	}		
}

public void destroy() {	}	

}[/code]

[code]public class EspecialidadeService {

@Inject private Session session;
	

public void excluir(Especialidade especialidade) {
	this.session.delete(especialidade);

}[/code]

É simples, Session não faz parte da especificação JPA, logo, você terá vários problemas,
Sugiro, fortemente, que mude para JPA e use o EntityManager.

Dá para fazer sim! Eu uso no meu projeto. Segue usando o hibernate Statistics.
Ob.: Ele nunca entrou no if do sessão != null. Funcionou perfeitamente.

package br.com.sustentar.dao;

import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.PersistenceUnit;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

/**
 *
 * @author Thiago Na fábrica de sessão é utilizado um singleton. Ou seja,
 * variáveis private static para abrir a fábrica e declarar a variável do tipo
 * SessionFactory. No método abreFabrica(), declara-se uma variável do tipo
 * Configuration e dá um new na AnnotationConfiguration(). Depois adiciona um
 * configure com o lugar do xml do hibernate. Iguala a variável da sessão com o
 * buildSessionFactory(). No final, retorna a variável de sessão. 
 */
public class FabricaSessao implements Serializable {

    
    private static SessionFactory sf;
    @PersistenceUnit
    private Session session;

    public void criaSessaoFactory() {
        Configuration cfg = new AnnotationConfiguration();
        cfg.configure("/br/com/sustentar/dao/hibernate.cfg.xml");
        sf = cfg.buildSessionFactory();
    }

    @Produces
    @RequestScoped
    public Session abreSessao() {
        if (sf == null) {
            criaSessaoFactory();
        }
        if (session != null) {
            System.out.println("***************************************************************");
            System.out.println("******************** Sessão não está nula ******************** ");
        }

        session = sf.openSession();
        System.out.println("  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  ");
        System.out.println("************ Numero de Sessão abertas ****** " + sf.getStatistics().getSessionOpenCount());
        System.out.println("************ Sessão fechada *********.... " + sf.getStatistics().getSessionCloseCount());
        System.out.println("XXXXXXXXXXXXXXXXXX  ConnectCount Sessão statics  XXXXXXXXXXXXXX " + sf.getStatistics().getConnectCount());
        System.out.println("Quantidade total de Transacoes:" + sf.getStatistics().getTransactionCount());
        System.out.println("Quantidade de Transacoes ok:" + sf.getStatistics().getSuccessfulTransactionCount());
        System.out.println("Consulta mais demorada :" + sf.getStatistics().getQueryExecutionMaxTimeQueryString());
        System.out.println("  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  ");
        return session;
    }

    public void fechaSessao(@Disposes Session session) {
        System.out.println("************ fechando a sessao *********** .... ");
        session.close();
    }
}

O que você quer não é criar um producer method?

[code]@ApplicationScoped
public class ResourcesProducer {

@Produces
@PersistenceContext( unitName = "nome-do-persistence-unit")
private EntityManager entityManager;

@Produces
public Session getSession() {
	return (Session) entityManager.getDelegate();
	
}

}[/code]

Depois é só injetar o objeto Session:

[quote=rodrigo.uchoa]O que você quer não é criar um producer method?

[code]@ApplicationScoped
public class ResourcesProducer {

@Produces
@PersistenceContext( unitName = "nome-do-persistence-unit")
private EntityManager entityManager;

@Produces
public Session getSession() {
	return (Session) entityManager.getDelegate();
	
}

}[/code]

Depois é só injetar o objeto Session:

Mas é usando o SessionFactory e não o entityManager. Pois pode ser que a aplicação nem tenha o arquivo de persistence. Dá forma que eu fiz funciona sem o entityManager.

//