CDI com Tomcat e Hibernate

4 respostas
S

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?

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;
	}

}
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() {	}	
}
public class EspecialidadeService {
	
	@Inject private Session session;
		
	
	public void excluir(Especialidade especialidade) {
		this.session.delete(especialidade);
}

4 Respostas

D

É 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.

T

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();
    }
}
R

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

@ApplicationScoped
public class ResourcesProducer {

	@Produces
	@PersistenceContext( unitName = "nome-do-persistence-unit")
	private EntityManager entityManager;
	
	@Produces
	public Session getSession() {
		return (Session) entityManager.getDelegate();
		
	}
}

Depois é só injetar o objeto Session:

@Inject private Session session;
T
rodrigo.uchoa:
O que você quer não é criar um producer method?
@ApplicationScoped
public class ResourcesProducer {

	@Produces
	@PersistenceContext( unitName = "nome-do-persistence-unit")
	private EntityManager entityManager;
	
	@Produces
	public Session getSession() {
		return (Session) entityManager.getDelegate();
		
	}
}

Depois é só injetar o objeto Session:

@Inject private Session 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.

Criado 6 de fevereiro de 2014
Ultima resposta 29 de out. de 2014
Respostas 4
Participantes 4