JPA : Como gerenciar o EntityManagerFactor e EntityManager?

Oi pessoal, tudo bem ?

Eu estou começando um projeto em JSF, preciso adicionar o acesso ao banco de dados ao projeto, gostaria de fazê-lo com o JPA.
Depois de ler bastante sobre, vi a diferença entre as transações ‘Resource Local’ e ‘JTA’.

Tentei várias vezes configurar o acesso via JTA, mas não consegui, então vou usar o ‘Resource Local’ mesmo com o EclipseLink 2.3.
Agora preciso criar uma forma adequada de criar os DAO’s porém estou preocupado com o EntityManagerFactory, já que ele é um recurso muito custoso.

Então gostaria de saber como vocês gerenciam o EntityManagerFactory e o EntityManager.
Estou pensando em fazer os DAO’s herdarem de uma classe ‘DAO’ os métodos de abrir/ criar o EntityManager, mas isso será o suficiente ?

Quando devo fechar o EntityManager e EntityManagerFactory ?

Abraços pessoal, obrigado pela ajuda.

Crie suas classe de dao como interface e faça a implementação dos metodos em outra classe exp: DaoImpl.

Eu não acho uma boa idéia acoplar a obtenção do EntityManager no DAO. Se você criar testes de integração para os seus DAOs vai entender porque complica. Eu acho mais interessante que o DAO receba o EntityManager através de um settter, pois se você tiver que criar o EntityManager dentro do DAO, você também vai ter que controlar transações dentro dele, o que é um acoplamento bastante forte. Eu não conheço o ciclo de vida do JSF, mas eu criaria o EntityManagerFactory no startup da aplicação e colocaria em algum cache. Depois, para cada requisição, recupero a factory, crio um EntityManager, abro a transação, processa a regra de negócio, e por fim, commit ou rollback, dependendo do sucesso ou falha do processamento. Não é performático, mas é a maneira mais simples que eu vislumbro. Acho que qualquer coisa mais complicada vale a pena usar um JBoss ou Spring da vida e usar as facilidades do container.

Tem varias formas abordagens:
*)Manualmente:

  1. SessionInView - http://www.guj.com.br/java/205965-open-session-in-view-com-jpa
  2. Thread-Local - http://fernandofranzini.wordpress.com/2011/09/05/escopo-thread-local/
    *) Fazendo alguem gerenciar para vc
  3. Configurando um container light como Spring - Veja o livro Spring in Action.

Acho que pode te ajudar http://code.google.com/p/jpa-component/wiki/Doc_PT_Br

Bom dia pessoal,

Tópico não é muito recente, mas estou iniciando um projeto financeiro, não é tão grande (mas intensão é ser futuramente), quero inicialmente hospedar na web, mas estou em dúvida em que tecnologia utilizar para implementar a camada de persistencia.
Utilizar a implementação do JPA, com os EntityManager e EntityManagerFactory e como fazer o gerenciamento dos mesmo (Open session in view, ou outra implementação, um JpaUtil), ou utilizar apenas hibernate sem implementação do JPA, com as sessions, um HibernateUtil.

Valeu.

Exemplo de uso especificação JPA independente de implementação com o uso do componente

http://code.google.com/p/jpa-component/wiki/Doc_PT_Br

package br.teste.pacote;

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

import br.com.jpa.component.ConfigPersistence;
import br.com.jpa.component.Configuration;

public class TestJPA {

        public static void main(String[] args) {
                
                Configuration configuration = ConfigPersistence.getInstanceConfiguration();
                
                EntityManagerFactory factory = configuration.createEntityManagerFactory();

                EntityManager em = factory.createEntityManager();
                
                Query query = em.createQuery("SELECT e FROM Cliente e ");

                List<Cliente> clientes = (List<Cliente>)query.getResultList();
                
                for(Cliente cliente : clientes) {

                        System.out.println(cliente.getNome());

                }
        }
}

[quote=vinicius8891]Bom dia pessoal,

Tópico não é muito recente, mas estou iniciando um projeto financeiro, não é tão grande (mas intensão é ser futuramente), quero inicialmente hospedar na web, mas estou em dúvida em que tecnologia utilizar para implementar a camada de persistencia.
Utilizar a implementação do JPA, com os EntityManager e EntityManagerFactory e como fazer o gerenciamento dos mesmo (Open session in view, ou outra implementação, um JpaUtil), ou utilizar apenas hibernate sem implementação do JPA, com as sessions, um HibernateUtil.

Valeu.[/quote]

Coloque algum framework para fazer isso para vc - Web profile ou spring.

Ok obrigado Pessoal!

E aproveitando o tópico, estou com o seguindo problema para rodar um exemplo simples de aplicação com spring, segue o log do erro, procurei no guj uma solução, mas ainda não consegui solucionar meu problema.

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/ExemploBasicoSpring] threw exception java.io.FileNotFoundException: /content/categoria.xhtml Not Found in ExternalContext as a Resource at com.sun.faces.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:224) at com.sun.faces.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:265) at com.sun.faces.facelets.impl.DefaultFaceletFactory.getMetadataFacelet(DefaultFaceletFactory.java:201) at com.sun.faces.application.view.ViewMetadataImpl.createMetadataView(ViewMetadataImpl.java:114) at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:227) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:111) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:508) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Obrigado desde já

Segue os arquivos de config do spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context-3.0.xsd 
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
						http://www.springframework.org/schema/aop 
						http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
							
	<!-- ********************************************* -->
	<!-- Configuração do DataSource -->
	<!-- ********************************************* -->
	 
    <bean id="dataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<!-- Postgres configutarion -->
		<property name="driverClass" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_agenda" />
    	<property name="user" value="root" />
		<property name="password" value="123456" />
	</bean>
    
	<!-- Configuraçãoes relativas a acesso a dados -->
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

		<property name="dataSource" ref="dataSource"/>
		
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
		</property>
		<property name="jpaVendorAdapter">
			<bean
				class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="showSql" value="true" />
				<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
			</bean>
		</property>
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.query.substitutions">true 'S',false 'N',yes 'S',no 'N'</prop>
				<prop key="hibernate.query.jpaql_strict_compliance">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop> <!-- create | create-drop | validate | update -->
			</props>
		</property>
	</bean>
	
	<!-- Transaction Manager exclusivo para JPA -->
	<bean id="transactionManager"
		class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory"/>
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
		</property>
	</bean>
	
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context-3.0.xsd 
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
						http://www.springframework.org/schema/aop 
						http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

	<context:annotation-config />
	<context:component-scan base-package="br.com.exemplospring" />
	
	<!-- habilita suporte as anotações transacionais -->
	<tx:annotation-driven order="1" />
	
	<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
	<tx:advice id="txAdvice">
		<!-- the transactional semantics... -->
		<tx:attributes>
			<!-- all methods starting with 'get' are read-only -->
			<tx:method name="find*" read-only="true" />
			<tx:method name="count*" read-only="true" />
			<tx:method name="get*" read-only="true" />
			<tx:method name="busca*" read-only="true" />
			<tx:method name="lista*" read-only="true" />
			<tx:method name="carrega*" read-only="true" />
			<!-- other methods use the default transaction settings (see below) -->
			<tx:method name="*" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>
	
	<!-- Configuração do Aspecto das transações. -->
	<aop:config>
		<aop:pointcut id="serviceMethods"
			expression="execution(* br.com.exemplospring.service..*.*(..))" />
		<aop:advisor order="2" advice-ref="txAdvice"
			pointcut-ref="serviceMethods" />
	</aop:config>
	
</beans>