Listener [RESOLVIDO]

22 respostas
ricardocomp

Olá pessoal,

Eu estou implementado um Listener com o ServletContextListener para não precisar criar o EntityManagerFactory toda hora no meu DAO.

Na verdade eu quero retirar esse construtor da minha classe DAO genérica e passo-lo para o meu Listener, mas estou aprendendo a usar o Listener agora não sei exatemente como eu vou fazer isso, será que alguém poderia me dar uma ajuda?

public class DAOGenerico<T> implements InterfaceDAO<T> {    
    
    private EntityManager em; 
    private EntityManagerFactory emf;
    
    public DAOGenerico(){     
      emf = Persistence.createEntityManagerFactory("bancodados");     
      em = emf.createEntityManager();     
   }  
...
}

A minha classe Listener que já está mapeada no meu arquivo web.xml

public class ServletListener implements javax.servlet.ServletContextListener {

       
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("Servlet Context is initialized....");
                 
    }

    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("Servlet Context is destroyed....");

    }
}

Será que alguém poderia me dar uma ajuda?

[]'s.

22 Respostas

FernandoFranzini
A melhor abordagem para isso é colocar a EntityManagerFactory como singleton em uma classe a parte e reutilizado em outros lugares.... Pelo amor de Deus não crie a fabrica dentro dos DAOs....totalmente impraticavel.... Segue um modelo simples....
public class JPAUtil {
	
	private static EntityManagerFactory FABRICA;
	
	public synchronized static void carregarFabricaJPA() {
		if (FABRICA == null) {
			try {
				FABRICA = Persistence.createEntityManagerFactory("sistema");
				System.out.println("Fabrica JPA criada com sucesso.");
			} catch (Exception e) {
				e.printStackTrace();
				throw new IllegalStateException(
						"Erro na criação da fabrica JPA - " + e.getMessage());
			}
		}
	}
	
	public synchronized static void destruirFabricaJPA() {
		if (FABRICA != null) {
			try {
				FABRICA.close();
				System.out.println("Fabrica JPA destruída com sucesso.");
			} catch (Exception e) {
				System.out.println("Erro na destruição da fabrica JPA - " 
						+ e.getMessage());
				e.printStackTrace();
			}
		} 
	}
	
	public static EntityManager getSession() {
		if (FABRICA != null) {
			try {
				return FABRICA.createEntityManager();
			} catch (Exception e) {
				System.out.println("Erro na criação da sessão JPA - " 
						+ e.getMessage());
			}
		}
		throw new IllegalStateException("Fabrica JPA não foi carregada");
	}	
}

@WebListener
public class ListenerContexto implements ServletContextListener {

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		JPAUtil.carregarFabricaJPA();
	}

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		JPAUtil.destruirFabricaJPA();
	}
}

Nos Dao's vc usa:

@SuppressWarnings("unchecked")
	private List&lt;Carro&gt; pesquisar(String alias) throws Exception {
		EntityManager session = JPAUtil.getSession();
		try {
			Query q = session.createNamedQuery(alias);
			return q.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		} finally {
			session.close();
		}
	}
A

cara,

se vc tiver usando EJB, vc pode injeta-lo atraves @PersistenceContext.

t+

ricardocomp

Olá FernandoFranzini e alissonvla

eu adaptei o código do Fernando Franzini para o meu sistema porém estou recebendo a seguinte exceção:

java.lang.IllegalStateException: Fabrica JPA não foi carregada
	at br.icmc.usp.listener.JPAUtil.getSession(JPAUtil.java:46)
	at br.icmc.usp.dao.DAOGenerico.<init>(DAOGenerico.java:21)
	at br.icmc.usp.dao.DAOFactory.getDAO(DAOFactory.java:14)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.salvar(TesteBolsistaDAO.java:49)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.main(TesteBolsistaDAO.java:24)

FernandoFranzini e alissonvla será que vc’s ou alguém poderia me dar ajuda?

[]'s.

A

como eu acho q vc nao ta usando JEE 6, entao vc tem que registar o Listener no web.xml. pois ele nao deve ter passado no seu listener.

t+

ricardocomp

Alisson no meu arquivo web.xml eu coloquei as seguintes linhas:

<listener>
        <listener-class>br.icmc.usp.listener.ServletListener</listener-class>
    </listener>

e no terminal do tomcat está aparecendo a seguinte mensagem:

INFO: The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/ServletBolsista]] after start() had already been called. The second call will be ignored.
Fabrica JPA criada com sucesso.

Porém a exceção

java.lang.IllegalStateException: Fabrica JPA não foi carregada
	at br.icmc.usp.listener.JPAUtil.getSession(JPAUtil.java:46)
	at br.icmc.usp.dao.DAOGenerico.<init>(DAOGenerico.java:21)
	at br.icmc.usp.dao.DAOFactory.getDAO(DAOFactory.java:14)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.salvar(TesteBolsistaDAO.java:49)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.main(TesteBolsistaDAO.java:24)

ainda continua aparecendo, será que vc ou alguém poderia me dar uma ajuda?

[]'s.

A

so por curiosidade… rsrs

vc trocou o nome do persistunit aqui

FABRICA = Persistence.createEntityManagerFactory("sistema");

t+

FernandoFranzini

alissonvla:
so por curiosidade… rsrs

vc trocou o nome do persistunit aqui

FABRICA = Persistence.createEntityManagerFactory("sistema");

t+


Certeza que é…kkkkkkkk

ricardocomp

A verdade é q eu acho q está dando algum problema aqui na hora que eu chamo o JPAUtil.getSession();
na minhas classe DAOGenerico.

public class DAOGenerico<T> implements InterfaceDAO<T> {           
    
    EntityManager session = JPAUtil.getSession(); 

...

}

Mas não sei o q está acontecendo exatamente, será que vc FernandoFranzinial e alissonvla ou alguém poderia me dar uma ajuda?

[]'s.

ricardocomp

Pior q ñ é FernandoFranzini

FABRICA = Persistence.createEntityManagerFactory("bancodados");
A

cara,

pelo que eu vi da classe ta tudo certo, o que ta acontecendo que FABRICA ta chegando null no getSession, entao vc vai ter q dar um debuggada ai no seu codigo para ver o que está acontecendo.

t+

ricardocomp

Só por curiosidade FernandoFranzini

Para implementar o padrão de projeto Singleton até onde eu sei eu tenho q ter o contrutor privado ñ?

[]'s.

FernandoFranzini

Tenho muitos projetos funcionando com isso…
Veja q no listene é imprimido stack quando não carrega a fabrica…post ai o erro!

FernandoFranzini

ricardocomp:
Só por curiosidade FernandoFranzini

Para implementar o padrão de projeto Singleton até onde eu sei eu tenho q ter o contrutor privado ñ?

[]'s.


Não necessariamente…veja nesse caso não temos construtor pq a instancia é criada no método carregarFabricaJPA().
Poderíamos dizer que seria um cenário variação de singleton.

ricardocomp

Eu ñ preciso fazer algo como context.setAttribute(), para poder recuperar no meu DAO?

O problema é q eu ñ estou conseguindo recuperar a sessão com o

EntityManager session = JPAUtil.getSession();

[]'s.

FernandoFranzini

Para criar a sessão seu persistence.xml tem q estar ok!!!
Posta as exceptions ai…senão não tem com adivinhar…

ricardocomp

O meu arquivo persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="bancodados" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>br.icmc.usp.modelo.Departamento</class>
    <class>br.icmc.usp.modelo.Bolsista</class>
    <class>br.icmc.usp.modelo.Curso</class>
    <class>br.icmc.usp.modelo.Contrato</class>
    <class>br.icmc.usp.modelo.Pagamento</class>
    <class>br.icmc.usp.modelo.Orientador</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/gerenciador_bolsistas"/>
      <property name="javax.persistence.jdbc.password" value="Minha Senha Aqui"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>  
</persistence>
ricardocomp

A exeções que estão aparecendo na hora de fazer o teste com o meu DAO genérico é:

java.lang.IllegalStateException: Fabrica JPA não foi carregada
	at br.icmc.usp.listener.JPAUtil.getSession(JPAUtil.java:46)
	at br.icmc.usp.dao.DAOGenerico.<init>(DAOGenerico.java:21)
	at br.icmc.usp.dao.DAOFactory.getDAO(DAOFactory.java:14)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.salvar(TesteBolsistaDAO.java:49)
	at br.icmc.usp.testeDAO.TesteBolsistaDAO.main(TesteBolsistaDAO.java:24)

Fernando Franzini e Alisson ou alguém poderia me dar uma ajuda?

[]'s.

FernandoFranzini

Eu acho que seu erro é pq o listener de contexto não esta sendo chamado no deploy…

A

segue uma outra implementação

public class JPAUtil {
	private static JPAUtil instance;
	private EntityManagerFactory factory;

	private JPAUtil() {
		if (factory == null) {			
			factory = Persistence.createEntityManagerFactory("PERSIST_UNIT");
		}
	}

	public static JPAUtil getInstance() {
		if (instance == null) {
			instance = new JPAUtil();
		}
		return instance;
	}

	public EntityManager getEntityManager() {
		return factory.createEntityManager();
	}
	
	public void close(){
		if(factory != null){
			factory.close();
		}
	}
}

mas tem algo esquisito ai… rs

ricardocomp

Falaaa FernandoFranzini e alissonvla, consegui graça a ajuda de vc’s :smiley:

Alisson eu segui os seus conselhos e modifiquei a classe JPAUtil e deu certo.

Muito Obrigado FernandoFranzini e alissonvla pela ajuda de vc’s.

Um Forte Abraço.

A

ok… :smiley:

edysnipes

Olá,

Estou com o mesmo problema.

Já conseguiu resolver?

Criado 16 de setembro de 2011
Ultima resposta 27 de nov. de 2011
Respostas 22
Participantes 4