Hibernate + Annotations + Lazy=true

4 respostas
vivi_grieco

Olá a todos,
estou usando hibernate 3 com annotations em uma aplicação.
Qnd eu tento buscar um objeto do bd, dá um erro:

SEVERE: could not initialize proxy - the owning Session was closed
org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed

Verificando na net, vi q resolveria o problema colocando no inicio da classe:

@Proxy(lazy=false,proxyClassName="br.gov.pa.tj.comarca.classe.Comarca")

Porém, em alguns casos, eu preciso q seja iniciado com lazy=true, o q nao está sendo possivel por causa do erro q está sendo gerado.
Alguém tem uma luz? :roll:

4 Respostas

_fs

Esse problema é comum. Veja:

Pessoa pessoa = ( Pessoa ) session.get( Pessoa.class, 1 );

session.close();

pessoa.getDocumentos(); // erro, pois a coleção seria inicializada agora, mas a sessão foi fechada

Há algumas soluções possíveis, uma delas está aqui e creio que será ideal para seu caso em que apenas em alguns momentos deseja que a coleção seja incializada:
http://article.gmane.org/gmane.comp.java.tapestry.user/23522

vivi_grieco

Oi Lipe,
tentei fazer do jeito q está nakele link q vc mandou, só q o erro continuou…
Tipo… o meu Dao é genérico, então tentei inicializar qnd eu chamo o método do DAO, apesar de q acho q isso tá errado… mas nao sei como poderia fazer :frowning:
O dao é esse:

public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao {
    
    public boolean inserir(Object o) {
        getHibernateTemplate().save(o);
        return true;
    }
    public Object alterar(Object o) {
        getHibernateTemplate().update(o);
        return o;
    }
    public boolean excluir(Object o) {
        getHibernateTemplate().delete(o);
        return true;
    }
    public Object selecionar(Integer pk) {
        Object o =getHibernateTemplate().load(getClasseVO(),pk);
        return o;
    }
    public Collection listar() {
        return getHibernateTemplate().find("from "+getClasseVO().getName());
        
    }
    
    protected  Class getClasseVO() {
        try {
            String classe = getClass().toString();
            classe = classe.replaceAll("dao", "classe");
            classe = classe.substring(6, classe.length() - 7);
            return Class.forName(classe);
        } catch (ClassNotFoundException e) {
            throw new HibernateException(e);
        }
    }
}

O erro ocorre qnd chamo o método “selecionar()”.
No meu JUnit eu fiz isso:

public void testSelecionar() {
		BeanFactory factory = new ClassPathXmlApplicationContext(
				"spring-hibernate.xml");
		ComarcaDAO dao = (ComarcaDAO) factory.getBean("ComarcaDao");
		Comarca comarca = (Comarca) dao.selecionar(new Integer(1));
		Hibernate.initialize(comarca);
		Hibernate.initialize(comarca.getUsuarios());
		System.out.println(comarca.getNome());
	}
_fs

Agora me diga como você quer adicionar um comportamento específico numa classe genérica? hehe

Talvez algo assim:

public Object selecionar( Integer pk, String[] as) {
    Object obj =getHibernateTemplate().load(getClasseVO(), pk);
    for( int i = 0; i < associationsToFetch.length; i++ )
    {
        Method method = obj.getClass().getMethod( "get" + associationsToFetch[ i ] );
        Hibernate.initialize( method.invoke( obj, null ) );
    }
}

public void test() {
    Pessoa pessoa = ( Pessoa ) dao.selecionar( new Integer( 1 ), new String[]{ "Enderecos", "Documentos", "Telefones" } );
}

edit: não sei se isso vai funcionar. O method.invoke() talvez se embanane com os proxies gerados pelo Hibernate. Testa e posta o feedback para nós! :smiley:

vivi_grieco

hehehe por isso q eu disse q achava q tava errado…
Valeu Lipe! :wink:

Criado 4 de agosto de 2005
Ultima resposta 4 de ago. de 2005
Respostas 4
Participantes 2