Open Session View – Hibernate Solução

solutionproblem

olá Pessoal,

No post de hoje vou falar de um problema que todos que estão trabalhando com Hibernate não está livre de se deparar com ele. É o velho LazyInitializationException que acontece e deixa o pobre do desenvolvedor stressado.

Neste post pretendo ser menos teórico e mais prático, pois tem muita coisa na net explicando o porque temos o LazyInitializationException, porém poucos explicaram de forma prática a solução. O mais próximo foi este site. Que se você reparar direito tem um pequeno erro no mapeamento do filtro.

Então aqui vou mostrar como resolver o problema, pois também fui afetado com este problema e levei umas quase 3 horas para resolver. E agora vejo que era algo simples, mas eu precisava entender o por que?! de cada exceção que vinha recebendo. Para este este post usei o post que está no Jboss Community, porém fiz algumas adaptações.

Lets go…

Vou usar a técnica de reutilização da informação então o Paulo da Caelum já fez uma abordagem excelente do porque desse problema , veja.

Desenvolvendo

Se você não quer desenvolver os codes a seguir, então mude o relacionamento para EAGER ao invés de usar o LAZY. Os codes a seguir é útil para quem necessita de ser LAZY o relacionamento.

  1. crie um novo package no seu projeto o meu chamei de : br.com.filtro

O pessoal do Jboss Community não colocou quais classes deveriamos importar, um programador inexperiente pode se atrapalhar e importar classes inapropriadas. Em função disso coloquei abaixo o código completo.

  1. Crie a classe HibernateSessionRequestFilter conforme abaixo: (fique atento ao meu comentário na classe)

    package br.com.filtro;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.hibernate.SessionFactory;
    import org.hibernate.StaleObjectStateException;
    
    import br.com.dao.DAO;
    
    public class HibernateSessionRequestFilter implements Filter {
    
    	 private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class);
    
    	    private SessionFactory sf;
    
    	    public void doFilter(ServletRequest request,
    	                         ServletResponse response,
    	                         FilterChain chain)
    	            throws IOException, ServletException {
    
    	        try {
    	          System.out.println("iniciando a transacao com o DB");
    	            sf.getCurrentSession().beginTransaction();
    
    	            // Call the next filter (continue request processing)
    	            chain.doFilter(request, response);
    
    	            // Commit and cleanup
    	            log.debug("Committing the database transaction");
    	          sf.getCurrentSession().getTransaction().commit();
    
    	        } catch (StaleObjectStateException staleEx) {
    	            log.error("This interceptor does not implement optimistic concurrency control!");
    	            log.error("Your application will not work until you add compensation actions!");
    	            // Rollback, close everything, possibly compensate for any permanent changes
    	            // during the conversation, and finally restart business conversation. Maybe
    	            // give the user of the application a chance to merge some of his work with
    	            // fresh data... what you do here depends on your applications design.
    	            throw staleEx;
    	        } catch (Throwable ex) {
    	            // Rollback only
    	            ex.printStackTrace();
    	            try {
    	                if (sf.getCurrentSession().getTransaction().isActive()) {
    	                    log.debug("Trying to rollback database transaction after exception");
    	                    sf.getCurrentSession().getTransaction().rollback();
    	                }
    	            } catch (Throwable rbEx) {
    	                log.error("Could not rollback transaction after exception!", rbEx);
    	            }
    
    	            // Let others handle it... maybe another interceptor for exceptions?
    	            throw new ServletException(ex);
    	        }
    	    }
    
    	    public void init(FilterConfig filterConfig) throws ServletException {
    	        //log.debug("Initializing filter...");
    	       // log.debug("Obtaining SessionFactory from static HibernateUtil singleton");
    	        sf = DAO.getSessionFactory();//vem da minha classe DAO
    	    }
    
    	    public void destroy() {}
    
    }
  2. Agora veja como está meu DAO:

    package br.com.dao;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class DAO {
    	private static ThreadLocal threadlocal = new ThreadLocal();
    	private static SessionFactory sessionFactory = new Configuration().configure().
    	buildSessionFactory(); 
    
    public DAO() {
    	// TODO Auto-generated constructor stub
    }
    public static  Session getSession(){
    	Session session = (Session) threadlocal.get();
    	if(session == null){
    		session = sessionFactory.openSession();
    		threadlocal.set(session);
    	}
    	return session;
    }
    	public void begin(){
    		getSession().beginTransaction();
    
    	}
    public void commit(){
    	getSession().getTransaction().commit();
    }
    
    public void rollback(){
    	getSession().getTransaction().rollback();
    }
    public void close(){
    	getSession().close();
    }
    public static void shutdown() {
    	// Close caches and connection pools
    	getSessionFactory().close();
    	}
    //passamos ele para o Filter
    public static SessionFactory getSessionFactory() {
    	return sessionFactory;
    }
    public static void setSessionFactory(SessionFactory sessionFactory) {
    	DAO.sessionFactory = sessionFactory;
    }
    
    }

Não precisei alterar nada da configuração padrão do hibernate.

  1. Abra seu arquivo hibernate.cfg.xml e adicione a linha abaixo:

    < property name=”hibernate.current_session_context_class”>thread  < /property>

  2. Salve e execute sua aplicação, veja se os println do Filter serão impressos (claro, os que estão nos catches nem devem aparecer). Em caso positivo está tudo ok.

  3. Agora teste várias vezes sua app e veja se verá o problema com LazyInitializationException. Aqui ele sumiu de vez, graças à deus.

A única coisa que mudei na classe HibernateSessionRequestFilter, foi informar meu SessionFactory e o resto o Filter fez o trabalho dele.

Bom vou ficando por aqui, espero que tenham gostado do post. Não posso deixar de agradecer ao autor Edson Gonçalves que contribuiu bastante para este post, desde a indicação do link, como as explanações pelo mesmo que foi contribuindo  até encontrar a solução, o colega Rafael Viana (GUJ) já tinha passado por um problema parecido e compartilhou sua experiência opinando como poderia ser resolvido.

Fica ai agora a versão em português do problema. Abracos, see you next post.

Pós-graduação em Java – Inscrições abertas.

A TNT Educacional oferece um ótimo curso de pós-graduação baseado em Java nas cidades de Campo Grande (MS), Lins, Ourinhos,  São Paulo, Campinas e Guarulhos.

O foco da pós-graduação “Engenharia de Componentes utilizando Java” é formar profissionais qualificados nas metodologias e processos de desenvolvimento Orientados a Objetos e as tecnologias Java com maior demanda nas principais empresas do mundo. Alguns dos diferencias do curso são:

  • Conteúdo (Padrões de Projeto Enterprise, Frameworks atuais, Produtos Open Source (Linux, Postgres));
  • Metodologia de ensino (aprendizagem baseada em problemas reais);
  • Professores (titulados e com experiência de mercado com desenvolvimento de software Java);
  • Ambiente virtual de ensino (universidade 24 horas) ;
  • Grade montada por especialistas no assunto;
  • Parceria com grandes empresas.

Além da ótima qualificação obtida, o aluno formado estará apto a dar aulas em cursos superiores, pois trata-se de um curso lato-sensu!

Enfim, convido a todos a darem uma olhada no site do curso. O Juliano Martins (Engenheiro de Software IBM) é um dos professores, especificamente do módulo de desenvolvimento Web com Java, portanto, fiquem a vontade para entrar em contato em caso de dúvidas.

Para mais informações, clique aqui.

Solucionando Communication link failure Hibernate com Pool + Mysql

olá Pessoal,

Hoje vou apresentar como resolver o problema abaixo quando temos nossa aplicação em produção e onde apostaríamos tudo que estava ok, pois em teste vc nunca tinha visto à exceção a seguir. Mas, pq em produção ela aparece e o cliente liga dizendo que está dando erro?

Bem, eu sofri muito com essa exceção, pesquisei bastante e vi várias dicas porém nenhuma delas eu conseguia resolver, dai conversando com Edson Gonçalves o mesmo me passou dois links importantes o qual encontrei a solução um está em inglês e outro é da Caelum explicando o outro problema que é broken pipe que é bem comum aparecer.

Lets go..

Posts Relacionado:

Mas, Por que temos essa exceção em PRODUÇÃO?

hibernateexcecaopool

A resposta é bem simples, se a conexão com seu banco ficar inativo por mais de 8 horas no caso do MySql, então o banco mata a conexão. E quando o cliente usando o pool de conexão tenta usar, já eh tarde demais.

Solucionando

Aqui estou usando o pool de conexão que é required em qualquer aplicação JEE, até por questão de manutenção, porém vou limitar o code apenas para meu arquivo context.xml.

Portanto abra seu arquivo META-INF/context.xml que faz o pool de conexão que você deve deixa-lo como o código a seguir:


  

 


Depois disso, manda o xml para produção, dar um restart no servidor e testa. Aqui resolveu. Até que fim.

o código anterior era assim:


  

 

Bem, espero que o post tenha ajudado, resolvi fazer esse post tendo como referencia o post em ingles, devido durante as minhas pesquisas não achei nada em português tão objetivo e direto para resolver o problema, só encontrava, discussões e opiniões de como poderia ser resolvido, mas nada de resolver. Agora já temos :). Mas, não se esqueça que isso tem efeitos apenas em produção.

abraços, see ya!!

Hibernate com Pool de Conexão

Olá Pessoal,

Hoje o post é bem simples, na verdade considero este como uma continuação do post sobre pool de conexão. Vou mostrar aqui como fazer hibernate usar o pool de conexão através de uma JNDI. Então será um post bem pequeno, já que vou adicionar apenas as informações referente ao arquivo hibernate.cfg.xml. Se quer comecar do zero, veja o post anterior.

Lets go…

Configurando

  1. Certifique-se que você tem no seu projeto o arquivo context.xml e web.xml configurado corretamente.

  2. Tanto faz se seu projeto é JSF Project ou Dynamic Web Project desde que seja para plataforma JEE.

  3. Não esqueça de adicionar os .jars do hibernate ao seu projeto, se tem dúvida veja neste post.

  4. Agora vamos para a parte mais simples, configurar o arquivo hibernate.cfg.xml. Então deixe seu arquivo conforme abaixo:




java:/comp/env/jdbc/blog
thread
org.hibernate.transaction.JDBCTransactionFactory
org.hibernate.dialect.MySQL5InnoDBDialect
0



 

Pronto observe que agora seu arquivo de configuração do hibernate ele “aponta” para o JNDI que criamos, e quando o schema ou caminho do BD mudar, vamos apenas alterar lá no JNDI e o hibernate já pega a nova informação. Simples não?

Abracos, espero que tenham gostado do post.

Rally Java EE – Indique e ganhe!

Folder-Rally-RallyDay

Olá Pessoal,

É com muito prazer que venho aqui, convida-los para o Rally Java EE OpenSource, concerteza será um Rally de conhecimentos. Eu gostaria muito de participar, mas no periodo do Rally estarei de férias e infelizmente não posso cancelar.

Em contato com a equipe do Rally, fizemos uma parceria bem interessante, para motivar mais ainda a participação. Aquele que indicar o nro maior de amigos para participar da competição, vai levar meu filho pra casa, ou seja, “Guia do Exame SCJP”.

E não para por ai, a equipe do Rally vai distribuir código de acesso para o SimSCJP Premium independente da categoria que que você vai concorrer.

Confira as informações aqui.


Então vai ficar de fora?

Não vou mentir, estou resistindo muito para não participar desse rally, independente dos prêmios, acredito que o conhecimento e experiência tem mais valor que qualquer produto de consumo, então se vc está com o tempo e vontade de participar, manda bala. A vida é curta e precisamos aproveitar cada momento dela. O que vc vai contar para seu filho e seu neto? Diga que pelo menos participou de um Rally.

Abracos pessoal e boa sorte no projeto de vocês!!