Hibernate 3 -- org.hibernate.LazyInitializationException: could not initialize proxy - the owning Se

Bom dia pessoal estou começando a usar Hibernate 3 e estou recebendo está mensagem:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: could not initialize proxy - the owning Session was closed
	org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:516)
	org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:423)
	org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
	org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
	org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

root cause

org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
	org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:53)
	org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:80)
	org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
	br.com.fts.bean.Empresa$$EnhancerByCGLIB$$e977926a.getRazaoSocial(<generated>)
	br.com.fts.action.EmpresaAction.edita(EmpresaAction.java:38)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	java.lang.reflect.Method.invoke(Unknown Source)
	org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276)
	org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:196)
	org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
	org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
	org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
	org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

note The full stack trace of the root cause is available in the Apache Tomcat/5.0.28 logs.
Apache Tomcat/5.0.28

Pelo que eu entendi ele está reclamando do meu getRazaoSocial() já olhei tudo e não encontrei nada de anormal… isso é alguma configuração ?

valeu…

Este erro acontece quando vc tenta dar um get em um atributo que está lazy=“true” no hbm e a sessao do hibernate já está fechada. Existem várias formas de contornar isso, fala mais da sua arquitetura pra ter como dar uma dica pra vc…

Olha só a arquitetura é a seguinte:

  1. Criei um formBean no meu struts-config.xml
    <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm" dynamic="true">
      <form-property name="empresa" type="java.lang.Long"/>
      <form-property name="usuario" type="java.lang.String"/>
      <form-property name="senha" type="java.lang.String"/>
    </form-bean>
  1. Criei JavaBean
public class Empresa implements Serializable {

	private Long codigo;
	private String razaoSocial;	
   
        // meus metodos get, set, equals e hashCode
}
  1. Criei um DAO
package br.com.fts.dao;

import br.com.fts.util.BaseDAO;
import br.com.fts.util.DAOException;
import br.com.fts.util.ConnectionFactory;
import br.com.fts.bean.Empresa;

import java.util.Collection;

import org.hibernate.Session;
import org.hibernate.HibernateException;


public class EmpresaDAO extends BaseDAO { 

	private static EmpresaDAO instance = null;
	
	public static synchronized EmpresaDAO getInstance() {
		if (instance == null) {
			instance = new EmpresaDAO();
		}
		return instance;
	}		
	
	public EmpresaDAO () {		
	}	
	
	public Collection listaTodos() throws DAOException {
	    return listaTodos(Empresa.class, null);
	}
	
	public Object procurar(Long codigo) {
		Session session = ConnectionFactory.getInstance().getSession();
		try {
			return (Empresa) session.load(Empresa.class, codigo);
		} catch (HibernateException e) {
			System.err.println("Hibernate Exception" + e.getMessage());
			throw new RuntimeException(e);
		} finally {
			if (session != null) {
				try {
					session.close();
				} catch (HibernateException e) {
					System.err.println("Hibernate Exception" + e.getMessage());
					throw new RuntimeException(e);
				}

			}
		}		
	}
}
  1. Meu mapeamento está dessa maneira:
<?xml version="1.0"?>
&lt;!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;

&lt;hibernate-mapping&gt;
    &lt;class name="br.com.fts.bean.Empresa" table="TB_EMPRESA" &gt;
        &lt;id name="codigo" column="CD_EMPRESA" type="long"&gt;
			&lt;generator class="sequence"&gt;
                &lt;param name="sequence"&gt;GE_CD_EMPRESA&lt;/param&gt;
	        &lt;/generator&gt;
        &lt;/id&gt;		

		&lt;property column="DC_RAZAO_SOCIAL" length="60" name="razaoSocial" not-null="true"	type="string" lazy="false"/&gt;        
		
    &lt;/class&gt;
&lt;/hibernate-mapping&gt;

Bem fora isso tenho uma classe de ConnectionFactory e o arquivo de configuração da conexão com meu BD que é Firebird… :slight_smile:

valeuuuu

[quote=leomc]Existem várias formas de contornar …[/quote] Quais por exemplo?

[]'s

Bom estive lendo um pouco não consegui achar a solução mais acredito que o erro deva estar no meu ConnectionFactory

package br.com.fts.util;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class ConnectionFactory {

	private static final SessionFactory sessionFactory;

	public static final ThreadLocal session = new ThreadLocal();

	static {
		try {
			Configuration cfg = new Configuration();
			cfg.configure("/hibernate.cfg.xml");
			sessionFactory = cfg.buildSessionFactory();
		} catch (MappingException e) {
			System.err.println("Mapping Exception" + e.getMessage());
			throw new RuntimeException(e);
		} catch (HibernateException e) {
			System.err.println("Hibernate Exception" + e.getMessage());
			throw new RuntimeException(e);
		}
	}

	public static Session currentSession() {
		Session s = (Session) session.get();
		if (s == null) {
			s = sessionFactory.openSession();
			session.set(s);
		}
		return s;
	}

	public static void closeSession() {
		Session s = (Session) session.get();
		if (s != null)
			s.close();
		session.set(null);
	}

}

deixei a sessão aberta e ele funciono… alguém tem alguma dica de como solucionar o problema??? estou ficando doidooo rsss

Mude de :

return (Empresa) session.load(Empresa.class, codigo);

para :

return (Empresa) session.get(Empresa.class, codigo);

Gente, desculpa desenterrar esse post, mas estava tendo o mesmo problema, de Lazy Initialization Exception.

Troquei o load pelo get como sugerido pelo amigo Alexandre Possebom e funcionou, mas gostaria de entender o porque. Qual a diferença entre eles?

Obrigado desde já

Basicamente load retorna uma proxy, e get retorna o objeto.

Como a Session do cara tinha side fechada, e ele pegava uma LazyInitializationException quando tentava usar o proxy do objeto.

Olha o meu caso:


org.hibernate.LazyInitializationException: could not initialize proxy - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
	at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
	at whereis.model.Usuario$$EnhancerByCGLIB$$b4c5fb31.getId(&lt;generated&gt;)
	at whereis.logic.LocalizadorLogic.main(LocalizadorLogic.java:34)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.vraptor.component.DefaultLogicMethod.execute(DefaultLogicMethod.java:117)
	at org.vraptor.interceptor.ExecuteLogicInterceptor.intercept(ExecuteLogicInterceptor.java:37)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.interceptor.SettingAndValidationInterceptor.intercept(SettingAndValidationInterceptor.java:131)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.interceptor.InjectionInterceptor.intercept(InjectionInterceptor.java:41)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.interceptor.ComponentLookupInterceptor.intercept(ComponentLookupInterceptor.java:58)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at whereis.logic.interceptor.DAOInterceptor.intercept(DAOInterceptor.java:25)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at whereis.logic.interceptor.AutorizadorInterceptor.intercept(AutorizadorInterceptor.java:27)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.interceptor.FlashScopeInterceptor.intercept(FlashScopeInterceptor.java:22)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.interceptor.RegisterAttributesInteceptor.intercept(RegisterAttributesInteceptor.java:38)
	at org.vraptor.core.InterceptorsLogicFlow.execute(InterceptorsLogicFlow.java:72)
	at org.vraptor.core.VRaptorExecution.execute(VRaptorExecution.java:90)
	at org.vraptor.core.DefaultController.execute(DefaultController.java:42)
	at org.vraptor.VRaptorServlet.service(VRaptorServlet.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Unknown Source)

to usando o vRaptor e hibernate. Sempre faço uma solicitação para um logic. Tenho somente uma página, que tem um corpo onde faz várias requisições AJAX. Na primeira requisição AJAX, depois de abrir a página inicial, ocorre tudo sem problemas, ja na segunda, ocorre a excessão. Todas as páginas requisitadas utilizam o acesso ao banco. Passam por um interceptor q cria uma sessão e no final a fecha. Qual pode ser o problema? E porque com o get não ocorre?

É melhor usar o get do que o load ou o contrário? Ou tanto faz em questão de desempenho?

Valew

Quanto ao desempenho o load é melhor pois só vai puxar os dados na hora que você usa-los, ele retorna uma proxy.

leia isso para entender melhor sobre o desempenho: http://www.hibernate.org/hib_docs/reference/en/html/performance.html

Quanto ao seu problema, com o get ele retorna o objeto na hora que você chama o get. Com o load, ele retorna uma proxy, e como não tem sessão o hibernate não consegue inicializar o Objeto e logo lança a excessão.

Links que lhe vão ser úteis:

Sobre Sessions: http://www.hibernate.org/42.html
Sobre OpenSessionInView: http://www.hibernate.org/43.html

Então cara,

No meu Interceptor eu crio uma instância de um DaoFactory:

public class DAOInterceptor implements Interceptor {

	private final DAOFactory factory = new DAOFactory();
	
	public void intercept(LogicFlow flow) throws LogicException, ViewException {
		
		flow.execute();
		
		if (factory.hasTransaction()) {
			factory.rollback();
		}
		factory.close();

	}
	
	@Out(key="whereis.dao.DAOFactory")
	public DAOFactory getFactory() {
		return factory;
	}

}

e no construtor do DaoFactory cria uma Session

public class DAOFactory {
	
	private final Session session;
	private Transaction transaction;
	
	public DAOFactory() {
		session = HibernateUtil.getSession();
	}
	
	public void beginTransaction() {
		this.transaction = this.session.beginTransaction();
	}
	
	public void commit() {
		this.transaction.commit();
		this.transaction = null;
	}
	
	public boolean hasTransaction() {
		return this.transaction != null;
	}
	
	public void rollback() {
		this.transaction.rollback();
		this.transaction = null;
	}
	
	public void close() {
		this.session.close();

	}
	
	
		
}
public class HibernateUtil {
	
	private static SessionFactory factory;

	static {
		
		Configuration conf = new AnnotationConfiguration();
		conf.configure();
		factory = conf.buildSessionFactory();
		
	}
	
	public static Session getSession() {

		return factory.openSession();
		
	}

}

Então não entendi porque está me acusando que não tenho uma sessão.

Desculpa ficar incomodando, mas essa dúvida ta me tirando horas de sono ha dias…

Valew

Olhando por cima parece estar tudo certo(mas ta tarde já, então não tenho 100% de certeza)… tem certeza que não tem algo fechando a conexão antes de usares o objeto carregado com o proxy?
Tenta chamar session.isOpen() pra ver se a sessão ainda está aberta quando fores utilizar o objeto carregado pelo .load

Também tem o Hibernate.initializate(Object obj) pra forçar a inicialização da proxy.

ninguem eh de ferro… também to com sono aqui hahaha

Boa noite

Vou por o isOpen para ver se ainda está aberta…

Valew

Depois posto o resultado.

Espero que positivo.