Melhor maneira de gerenciar conexão do JPA

3 respostas
R

Bom dia!

Desde que começei a trabalhar com Hibernate, percebi que a antiga maneira manual de |Abre conexao| Executa SQL | Fecha conexão | era muito trabalhosa e passivel a erros.
Descobri que usando o famoso OpenSessionInView com o Hibernate facilitaria muito as coisas. Mesmo abrindo e fechando a conexãp/transação, fica de uma forma transparente para meus ManagedBeans
Desde então, utilizo isso sempre em meus projetos, apenas adaptei para trabalhar com JPA:

Web.xml
<filter>
	<filter-name>JPASessionRequestFilter</filter-name>
	<filter-class>br.com.teste.JPASessionRequestFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>JPASessionRequestFilter</filter-name>
	<url-pattern>*.jsf</url-pattern>
</filter-mapping>
Meu Filter:
public class JPASessionRequestFilter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		try {
			JPAHelper.beginTransaction();
			chain.doFilter(request, response);
			JPAHelper.commitTransaction();

		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {	}

	public void destroy() {	}
}

Sendo assim, sempre que chamar qualquer action JSF, ele sempre abrirá minha conexão/transação, e comitará no final.
Tudo isso funciona perfeitamente, mas sempre tive a impressão de que esta implementação é um pouco frágil.
Projetos grandes sempre usam datasource dos application servers, mas na verdade nunca usei, sempre fiz usando Filters e sempre funcionou.

Qual é a real vantagem de se usar a transação controlada pelo contâiner ? Usando filtros, não fico acoplado no contâiner.
Como um contâiner com o JBoss AS, por exemplo, pode me dar uma garantia de escalabilidade e confiança nas transações e conexões JPA ?

3 Respostas

R

Caso eu configure o pool do C3P0 direto no meu persitence.xml, faria grandes diferença usar um datasource do application server ?

C
rubao123:
Bom dia!

Desde que começei a trabalhar com Hibernate, percebi que a antiga maneira manual de |Abre conexao| Executa SQL | Fecha conexão | era muito trabalhosa e passivel a erros.
Descobri que usando o famoso OpenSessionInView com o Hibernate facilitaria muito as coisas. Mesmo abrindo e fechando a conexãp/transação, fica de uma forma transparente para meus ManagedBeans
Desde então, utilizo isso sempre em meus projetos, apenas adaptei para trabalhar com JPA:

Web.xml
<filter>
	<filter-name>JPASessionRequestFilter</filter-name>
	<filter-class>br.com.teste.JPASessionRequestFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>JPASessionRequestFilter</filter-name>
	<url-pattern>*.jsf</url-pattern>
</filter-mapping>
Meu Filter:
public class JPASessionRequestFilter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		try {
			JPAHelper.beginTransaction();
			chain.doFilter(request, response);
			JPAHelper.commitTransaction();

		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {	}

	public void destroy() {	}
}

Sendo assim, sempre que chamar qualquer action JSF, ele sempre abrirá minha conexão/transação, e comitará no final.
Tudo isso funciona perfeitamente, mas sempre tive a impressão de que esta implementação é um pouco frágil.
Projetos grandes sempre usam datasource dos application servers, mas na verdade nunca usei, sempre fiz usando Filters e sempre funcionou.

Qual é a real vantagem de se usar a transação controlada pelo contâiner ? Usando filtros, não fico acoplado no contâiner.
Como um contâiner com o JBoss AS, por exemplo, pode me dar uma garantia de escalabilidade e confiança nas transações e conexões JPA ?

Penso eu que o melhor gerenciador de transações e conexões JPA seja o EntityManager!

R
Carlos_ds_jar:
Penso eu que o melhor gerenciador de transações e conexões JPA seja o EntityManager!
Sim, já estou usando o EntityManager. A minha classe JPAHelper faz isso:
package br.com.test.testingConsole.utils;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class JPAHelper {

	private static EntityManagerFactory entityManagerFactory;
	private static EntityManager entityManager;
	
	static{
		entityManagerFactory = Persistence.createEntityManagerFactory("TestPU");
		entityManager = entityManagerFactory.createEntityManager();
	}
	
	public static void beginTransaction(){
		entityManager.getTransaction().begin();
	}
	
	public static void commitTransaction(){
		entityManager.getTransaction().commit();
	}
	
	public static void persist(Object object){
		entityManager.persist(object);
	}
	
	public static void update(Object object){
		entityManager.merge(object);
	}
	
	public static Object getObjectByID(Class<?> clazz, Object id){
		return entityManager.find(clazz, id);
	}
	
	public static List getAll(Class clazz){
		Query query = JPAHelper.entityManager.createQuery("from " + clazz.getName());
		return query.getResultList();
	}
	
}

Minuha dúvida é:
O que eu faço é o ideal ou um Application Server pode me ajudar a melhorar isso ?

Criado 27 de julho de 2010
Ultima resposta 28 de jul. de 2010
Respostas 3
Participantes 2