Em todo exemplo que eu vejo de JPA, o EntityManagerFactory é um singleton (ou injetado), enquanto que o EntityManager é sempre instanciado um novo a cada chamada de método service.
Por que o EntityManager não pode também ser um Singleton (ou injetado) ??
No meu caso eu só trabalho com um PersistenceUnit. Mas de qualquer forma, nada impede que eu use singleton para mais de um persistenceUnit.
O principal motivo de eu estar fazendo este questionamento, é que se eu uso Singleton, a página inicial do meu site demora 5 segundos para carregar, enquanto que se eu instancio o entityManager a cada chamada de cada método, o tempo passa para 12 segundos, uma diferença muito grande, não?
Descobri que a diferença (de 4 segundos para 12 segundos) é por causa do cache que o JPA faz.
Na primeira vez que abrem a página inicial do meu site, demora uns 20 segundos para abrir. Mas depois, se eu estiver usando singleton, o tempo cai para 4 segundos, senão cai para 12 segundos.
Se eu instanciar o EntityManager a cada chamada de cada método service, eu estou jogando fora esse recurso de cache do JPA, não???
Sim e eu concordo com você tanto que eu também uso um singleton para minhas aplicações.
Quando o projeto de empresa não me cobra tecnologia específica, eu instancio o entityManager nas minhas classes beans do EJB através da annotation @PersistenceContext pois é ele quem vai manter o controle das minhas transações. eu nem preciso instanciar essa classe para obter uma instancia dela… o próprio ejb observa e faz a inicialização… quando o programa ainda está fazendo deploy.
daí… para não haver problemas com instancias e me facilitar com Sessions eu faço da seguinte forma:
public static synchonized PessoaDAO getInstance(EntityManager em){
if(pessoaDAO == null){
pessoaDAO = new PessoaDAOImpl();
pessoaDAO.setEm(em);
}
return pessoaDAO;
}
Enfim… na hora de fazer alguma ação… basta eu acessar essa classe estática para fazer ações com a classe PessoaDAO por exemplo.
Entendi onde quer chegar. E tenho certeza que muitas pessoas usam uma classe Singleton para isso. Até mesmo os frameworks que dão suporte ao JPA usam também uma mesma instancia para as ações com EntityManager.
O problema do próprio framework já ter uma classe dessas cai no mesmo problema que eu falei anteriormente… bom, mas pensando melhor… realmente… o JPA já poderia ter uma própria classe singleton EntityManager. Bastava apenas especificar no persistence.xml as classes pertencentes ao unitName.