JPA - createEntityManagerFactory

3 respostas
M

pessosal.

Estou desenvolvendo uma aplicação desktop com JPA. Nesta aplicação tenho várias entidades e para cada uma delas tenho um classe para gerenciar a entidade (CRUD). Mas o detalhe é o seguinte, cada vez que faço a instância destas classes estou criando um emf (emf = Persistence.createEntityManagerFactory(“SGAE_PU”):wink: e após o uso do gerenciador estou aplicando um emf.close(). Isto é o correto? Para este tipo de situação não seria mais interessante criar o objeto emf no inicio da aplicação e fecha-lo somente ao encerrar a aplicação?

Obrigado.

3 Respostas

M

este objeto deve ser criado apenas uma vez… é muito custoso cria-lo…entum coloque dentro de um bloco estatico… e só cria uma vez…

C

Se você está fazendo uma aplicação Web, uma solução legal é criar um context listener que inicializa o EMF quando o contexto é carregado e fecha quando é descarregado.

Já usei essa solução, fica mais ou menos assim:

public class JPAListener implements ServletContextListener {
    

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        EntityManagerFactorySingleton.getEntityManagerFactory();
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        EntityManagerFactorySingleton.getEntityManagerFactory().close();
    }
    
}

e o singleton copiei de algum lugar, acho que do site do Hibernate:

public class EntityManagerFactorySingleton {
    
    private static final EntityManagerFactory emf;
    
    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            emf = Persistence.createEntityManagerFactory("xxxxxx");
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static EntityManagerFactory getEntityManagerFactory() {
        return emf;
    }
}

Desta forma o EMF é iniciado quando o Singleton é carregado.

J

Exatamente isso, vc pode criar uma classe util, ± como esta.

public final class PersistenceUtil {
	
	private static final String UNIT_NAME = "trip";
	
	private static EntityManagerFactory FACTORY;
	
	public static final ThreadLocal<EntityManager> SESSION = new ThreadLocal<EntityManager>();
	
	public static EntityManager currentEntityManager() {
		EntityManager manager = (EntityManager) SESSION.get();
        if (manager == null) {	
        	loadInstance();
        	manager = FACTORY.createEntityManager();
            SESSION.set(manager);
        }
        return manager;
    }
	
	public static void closeEntityManager() {
		EntityManager manager = (EntityManager) SESSION.get();
        if (manager != null) {
        	manager.close();
        }
        SESSION.set(null);
    }

	private static synchronized void loadInstance() {
		if (FACTORY == null) {
			FACTORY = Persistence.createEntityManagerFactory(UNIT_NAME);
		}
	}
	

}
Criado 7 de junho de 2007
Ultima resposta 7 de jun. de 2007
Respostas 3
Participantes 4