Problemas nas sessões do hibernate

Olá pessoal…
estou tendo dificuldades aqui na manipulação correta das sessions e transactions do hibernate…
queria saber qual a melhor maneira de manipulá-las…
eu estou abrindo e fechando as sessões nos métodos das classes DAO…
exemplo, esse é meu ClienteDAO

public class ClienteDAO {
    
    public ClienteDAO() {
    }

    Session sessao = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = sessao.beginTransaction();
    
    public void insere(Cliente cli) throws Exception {
        sessao.save(cli);
        tx.commit();
        sessao.close();
    }

    public Cliente get(Long id) {
        List clientes = sessao.createQuery("from Cliente c where c.id='"+id.toString()+"'").list();
        tx.commit();
        sessao.close();
        for ( Iterator iter = clientes.iterator(); iter.hasNext(); ) {
            Cliente c = (Cliente) iter.next();
            return c;
        }
        return null;
    }
    (...)

mexendo apenas com o cliente tá indo ok… o grande problema está quando eu começo a adicionar os outros atributos do Cliente… como Dependente, Endereço do Dependente, etc… ele fica passando null…
eu já fiz inúmeros testes e acredito que seja por causa da forma como estou fazendo o commit e o close…
mas tbm suspeito que seja meu mapeamento…

esse é meu mapeamento de cliente:

<hibernate-mapping>
(...)
        <list name="dependentes" inverse="true" cascade="all" lazy="true" >
            <key column="id_cliente"/>
            <list-index column="posicao"/>
            <one-to-many class="model.Dependente"/>
        </list>
(...)
</hibernate-mapping>

esse é o mapeamento de dependente:

       <many-to-one 
            name="endereco"                           
            class="model.Endereco" 
            column="endereco"
            cascade="save-update" 
            unique="true"/>

Agradeço muito qualquer ajuda.

Abraços!

Olá Amigo,
acredito que teus mapeamentos estao ok.

Porem, a abertura de fechamento da sessao e transacao que pode estar incorreto.

Perceba que vc abre a sessao e transacao ao carregar sua classe DAO. Porem, para cada método dessa classe, vc fecha a sessao e transacao.

Caso vc utilize 2 metodos da mesma instancia de DAO, nao existirá mais sessao nem transacao para ele “comitar”.

algo assim:

dao = new ClienteDAO(); // abriu sessao e transacao

dao.get(1); //fechou a sessao e transacao (linha 2 e 3 do teu metodo)

dao.insere(clienteNovo); 

//ops... dentro do metodo acima vc tenta salvar a entidade e "comitar" a
//transacao... mas a transacao já foi "comitada" no metodo get.

Minha sugestao:

  • Abra uma nova transacao em cada um dos metodos que realiza insercao/atualizacao no banco.

  • Mantenha a sessao aberta por toda a execucao do teu DAO. Se possivel, utilize a mesma sessao durante toda a execucao do seu programa (desktop) ou durante todo o processamento de uma requisicao (web).

Pq isso? bom, quando vc inicia e finaliza a transacao, vc garante que os dados serao persistidos no SGBD.

Quando vc reutiliza a sessao, vc aproveita o cache de primeiro nivel do hibernate, e nao vai no banco de dados recuperar uma informacao que vc já possui :slight_smile:

Espero ter ajudado…

Meu caro Insônia,

muito obrigado por sua pronta resposta…
fiz as alterações que vc me sugeriu e vários problemas foram resolvidos…
mas o sistema continuava retornando null index column for collection e eu realmente já estava desistindo por hoje até q fui pesquisar mais sobre o erro, e vi que existia uma incompatibilidade da relação bidirecional (inverse=“true”) com as versões do hibernate anteriores à 3. (vide http://www.hibernate.org/193.html ) … mesmo usando a versão 3 do hibernate eu tentei não usar o inverse="true" e, tcharamm, funcionou …

meu mapeamento do Cliente ficou:

        <list name="dependentes" inverse="false" cascade="all" lazy="true" >
            <key column="id_cliente"/>
            <list-index column="posicao"/>
            <one-to-many class="model.Dependente"/>
        </list>

incrível como esse único detalhe me fez perder toda a madrugada… hehehe

novamente muito obrigado pela ajuda.

Abraços!