JPA...Duvida em Singleton com EntityManagerFactory?

5 respostas
P

Olá,

duvida no acesso a EntityManagerFactory pois criei como Singleton
e ao rodar conforme abaixo está trazendo duas instancias diferentes
da EntityManagerFactory fiz porque vai ter varios acessos e queria
que pegasse somente uma instancia ???

É correto fazer isso ou JPA não aceita ???

abs

public class PersistenceServiceFactory {
	private static EntityManagerFactory emf = null;
	private static EntityManager        em  = null;
	private static PersistenceServiceFactory instance = new PersistenceServiceFactory ();
	
	
	private PersistenceServiceFactory(){
		
	}
    public static PersistenceServiceFactory getInstance() {
		return instance;
	}

	public static EntityManager create() {
    	try{
    		emf = Persistence.createEntityManagerFactory("ims");
            System.out.println("Factory = "+emf);
            em = emf.createEntityManager();
            System.out.println("Manager = "+em);
            
    	}catch(Exception e){
    		System.out.println("Não conseguiu acesar o Banco ");
    	}
    	return em;	
    }
}
Factory = org.hibernate.ejb.EntityManagerFactoryImpl@15d601f
Manager = org.hibernate.ejb.EntityManagerImpl@151b0a5
----

Factory = org.hibernate.ejb.EntityManagerFactoryImpl@121fd61
Manager = org.hibernate.ejb.EntityManagerImpl@82254d

5 Respostas

T

Troque sua chamada para:

Vc pode sim, a meu ver utilizar um EMF como singleton.

G

Cara,

Criar entityManagerFactory é uma operação pesada, justamente por isso ele é uma factory, a idéia é que exista poucas(preferencialmente uma, mas em alguns casos são necessárias mais)

Em compensação o createEntityManager é uma operação barata.

Seu codigo deveria ser:

public static EntityManager create() {  
         try{  
             if ( emf == null )  {
                 emf = Persistence.createEntityManagerFactory("ims");  
                 System.out.println("Factory = "+emf);  
             }
             em = emf.createEntityManager();  
             System.out.println("Manager = "+em);  
               
         }catch(Exception e){  
             System.out.println("Não conseguiu acesar o Banco ");  
         }  
         return em;    
     }

Agora, se seu caso for(estou começando a suspeitar que seja) um caso típico de quem trabalha com SAAS(Software as a Service) onde cada cliente possui um banco de dados, vc terá que usar uma outra abordagem completamente diferente, se não sua aplicaçao vai ficar MTO pesada. Pq entityManager é algo que deve ser criado com frequencia, e se vc vincular a criação de um EntityManagerFactory a isso sua aplicação vai ficar bem lenta sem necessidade.

Se for esse seu caso, avise para que eu possa te indicar um post que eu mesmo criei pois tive que enfrentar esse problema recentemente.

Abs,

L

Olá, tenho uma situação igual a que vc comentou neste post, onde cada cliente tem sua base. Você poderia me indicar o post que escreveu para resolver essa situação!
Grato pela ajuda.

Leonardo.

GraveDigger:
Cara,

Criar entityManagerFactory é uma operação pesada, justamente por isso ele é uma factory, a idéia é que exista poucas(preferencialmente uma, mas em alguns casos são necessárias mais)

Em compensação o createEntityManager é uma operação barata.

Seu codigo deveria ser:

public static EntityManager create() {  
         try{  
             if ( emf == null )  {
                 emf = Persistence.createEntityManagerFactory("ims");  
                 System.out.println("Factory = "+emf);  
             }
             em = emf.createEntityManager();  
             System.out.println("Manager = "+em);  
               
         }catch(Exception e){  
             System.out.println("Não conseguiu acesar o Banco ");  
         }  
         return em;    
     }

Agora, se seu caso for(estou começando a suspeitar que seja) um caso típico de quem trabalha com SAAS(Software as a Service) onde cada cliente possui um banco de dados, vc terá que usar uma outra abordagem completamente diferente, se não sua aplicaçao vai ficar MTO pesada. Pq entityManager é algo que deve ser criado com frequencia, e se vc vincular a criação de um EntityManagerFactory a isso sua aplicação vai ficar bem lenta sem necessidade.

Se for esse seu caso, avise para que eu possa te indicar um post que eu mesmo criei pois tive que enfrentar esse problema recentemente.

Abs,

L

nenhuma dessas forma é realmente a mais adequada.... em um ambiente multi-thread é seguro se precaver contra concorrencia, veja essa abordagem...

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

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.ejb.HibernateEntityManager;

public class HibernateUtil {
	private static EntityManagerFactory emf;

	public static EntityManagerFactory getEmf() {
		if (emf == null){
			synchronized (HibernateUtil.class) {
				if (emf == null)
					try {
						emf = Persistence.createEntityManagerFactory("sua_unidade_de_persistencia");
					} catch (RuntimeException ex) {
						Logger.getLogger(HibernateUtil.class).fatal("não foi possível carregar a unidade de persistencia", ex);
						throw ex;
					}
			}
		}
		return emf;
	}

	public static EntityManager createEm() {
		try {
			return getEmf().createEntityManager();
		} catch (RuntimeException ex) {
			Logger.getLogger(HibernateUtil.class).error("falha ao criar EntityManager", ex);
			throw ex;
		}
	}

	public static Session createSession() {
		return ((HibernateEntityManager)createEm()).getSession();
	}
}
G

leonardo.carbone:
Olá, tenho uma situação igual a que vc comentou neste post, onde cada cliente tem sua base. Você poderia me indicar o post que escreveu para resolver essa situação!
Grato pela ajuda.

http://www.guj.com.br/posts/list/128322.java#692135

Abs

Criado 12 de janeiro de 2009
Ultima resposta 15 de out. de 2009
Respostas 5
Participantes 5