terça-feira, 29 de junho de 2010

Hibernate Exception: Illegal attempt to associate a collection with two open sessions

Esse problema começou a correr quando passei a utilizar o pattern (Open Session In View). E ocorre quando temos uma collection, por exemplo, em um relacionamento @OneToMany.


No meu caso, quando eu adicionava um objeto a collection dava tudo certo:

public void saveMensagem(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      mensagem.setChamado(chamado);
      mensagem.setUsuario(LoginMB.getUsuarioLogado());
      chamado.getMensagens().add(mensagem);
      dao.update(chamado);
   }catch (Exception e) {
      e.printStackTrace();
   }
}

O problema ocorria quando eu fazia um update no objeto que contem a collection, sem fazer alterações na mesma:

public void save(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      if(chamado.getUsuario() == null){
         chamado.setUsuario(LoginMB.getUsuarioLogado());
         dao.save(chamado);
      }else{
         dao.update(chamado);
      }
   }catch (Exception e) {
      e.printStackTrace();
   }
}


Para resolver o problema eu mudei de session.update para session.merge:

public void save(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      if(chamado.getUsuario() == null){
         chamado.setUsuario(LoginMB.getUsuarioLogado());
        dao.save(chamado);
      }else{
         dao.merge(chamado);
      }
   }catch (Exception e) {
      e.printStackTrace();
   }
}

6 comentários:

  1. VALEU VELHO SALVOU MEU DIA.
    tallescdc@gmail.com.
    obrigado dr.

    ResponderExcluir
  2. public void saveMensagem(ActionEvent event){
    dao = new ChamadoDao(HibernateUtil.getSession(),Chamado.class);
    try{
    mensagem.setChamado(chamado);
    mensagem.setUsuario(LoginMB.getUsuarioLogado());
    chamado.getMensagens().remove(mensagem);
    dao.update(chamado);
    // ou dao.merge(chamado);
    }catch (Exception e) {
    e.printStackTrace();
    }
    }

    O relacionamento deve estar corretamente mapeado para exclusão:

    Ex:

    @OneToMany(mappedBy="movimento", cascade = CascadeType.ALL ,orphanRemoval=true)
    private Collection lancamentos;

    ResponderExcluir
  3. Bom dia, Estou com o mesmo problema para exclusão.

    Porem não tem esse "orphanRemoval".

    como posso resolver?

    ResponderExcluir
  4. @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

    ResponderExcluir