Erro ao excluir aluno do banco

10 respostas
Jackye

Olá pessoal.

Tenho o seguinte:
Quando abro minha janela de listagem de aluno, tenho um botão para excluir do banco atraves da lista.
no meu botao tenho o seguinte método:

int linha = jTable1.getSelectedRow(); Aluno aluno = ((ListarAlunos) jTable1.getModel()).getObject(linha); if (aluno != null) { AlunoDAO.fabricaAlunoDAO().remover(aluno); } preencherTabela();

Esse é o metodo de preencher a tabela (Chamo ele lá no initcomponets):

private void preencherTabela() { jTable1.setModel(new ListarAlunos(AlunoDAO.fabricaAlunoDAO().findAll())); }

A ListarAlunos refere-se a uma classe que extende a AbstractTableModel:

package Visao;

import Dominio.Aluno;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class ListarAlunos extends AbstractTableModel{
    
     private List<Aluno> alunos;  
        private static final String[] col = {"Código","Nome","Matrícula"};  
      
        public ListarAlunos(List<Aluno> alunos){  
            this.alunos = alunos;  
            fireTableStructureChanged();  
        }  
      
        @Override  
        public int getRowCount() {  
            return alunos.size();  
        }  
      
        @Override  
        public int getColumnCount() {  
            return col.length;  
        }  
      
        @Override  
        public Object getValueAt(int rowIndex, int columnIndex) {  
            Aluno aluno = alunos.get(rowIndex);
            Object dado = null;
            switch (columnIndex){
                case 0:
                    dado = aluno.getCodUsuario();
                break;
                case 1:
                    dado = aluno.getNome();
                break;
                case 2:
                    dado = aluno.getMatricula();
                break;                   
            }
            return dado;  
        }  
      
        @Override  
         public void setValueAt(Object value, int row, int col) {  
            Aluno aluno = alunos.get(row);
            switch (col){
                case 0:
                    aluno.setCodUsuario((Integer) value);
                break;
                case 1:
                    aluno.setNome((String) value);
                break;
                case 2:
                    aluno.setMatricula((Integer) value);
                break;                 
            }            
            fireTableCellUpdated(row, col);  
         }  
      
          
        @Override  
        public boolean isCellEditable(int rowIndex, int columnIndex){  
            /* Aqui voce indica qual coluna vai ser editável ou não, 
             Abaixo, somente a primeira coluna não é editável */  
            return false;  
        }  
      
        @Override  
        public Class getColumnClass(int column){  
            // Aqui voce indica qual tipo de dado é retornado nas colunas  
            switch (column){
                case 0:
                    return Integer.class;
                case 1:
                    return String.class;
                case 2:
                    return Integer.class;                  
            }             
            return Object.class;
        }  
      
        public List<Aluno> getDataSet(){  
           // Aqui voce retorna todo o conjunto de dados  
           return alunos;  
        }  
      
        @Override  
        public String getColumnName(int column){  
            // Aqui define os nomes da colunas  
            return col[column];  
        }  
      
        public Object[] getRow(int row) {  
             // Aqui voce retorna um linha de registro inteira.  
             return new Object[]{alunos.get(row).getCodUsuario(),
                                 alunos.get(row).getNome(),
                                 alunos.get(row).getMatricula()};  
        }  
      
        public void removeRow(int row) {  
             // Aqui voce remove uma linha específica  
             alunos.remove(row);  
             fireTableDataChanged();  
        }  
      
        public void addRow(Object[] row) {  
            // Aqui voce acrescenta uma linha com um conjunto de registros específico  
            fireTableDataChanged();  
        }  
      
        public void addEmptyRow(){  
            // Aqui voce acrescenta uma linha em branco  
            fireTableDataChanged();  
        }  
        
        public Aluno getObject(int linha){
            return alunos.get(linha);
        } 
}

Quando executo a exclusão dá o seguinte erro:
[color=red] Illegal attempt to associate a collection with two open sessions [/color]

Não estou conseguindo visualizar essas sessões abertas!!

10 Respostas

williamdasflores

Acho que quando chama para listar, a sessão não esta sendo fechada.

mauricioadl

isso
Aluno aluno = ((ListarAlunos) jTable1.getModel()).getObject(linha);

nao deveria ser assim::?
Aluno aluno = ((Aluno) jTable1.getModel()).getObject(linha);

Jackye

Oi mauricioadl.

Se eu fizer assim:
Aluno aluno = ((Aluno) jTable1.getModel()).getObject(linha);
Dá um erro em: getObject(linha);

Pede pra criar um metodo desse tipo lá na classe.

Sendo que quando faço assim:
Aluno aluno = ((ListarAlunos) jTable1.getModel()).getObject(linha);
Esse getObject(linha); vem daqui:
public Aluno getObject(int linha){
            return alunos.get(linha);
        }
Lá da Classe ListarAluno.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Visao;

import Dominio.Aluno;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Jackeline
 */
public class ListarAlunos extends AbstractTableModel{
    
     private List<Aluno> alunos;  
        private static final String[] col = {"Código","Nome","Matrícula"};  
      
        public ListarAlunos(List<Aluno> alunos){  
            this.alunos = alunos;  
            fireTableStructureChanged();  
        }  
      
        @Override  
        public int getRowCount() {  
            return alunos.size();  
        }  
      
        @Override  
        public int getColumnCount() {  
            return col.length;  
        }  
      
        @Override  
        public Object getValueAt(int rowIndex, int columnIndex) {  
            Aluno aluno = alunos.get(rowIndex);
            Object dado = null;
            switch (columnIndex){
                case 0:
                    dado = aluno.getCodUsuario();
                break;
                case 1:
                    dado = aluno.getNome();
                break;
                case 2:
                    dado = aluno.getMatricula();
                break;                   
            }
            return dado;  
        }  
      
        @Override  
         public void setValueAt(Object value, int row, int col) {  
            Aluno aluno = alunos.get(row);
            switch (col){
                case 0:
                    aluno.setCodUsuario((Integer) value);
                break;
                case 1:
                    aluno.setNome((String) value);
                break;
                case 2:
                    aluno.setMatricula((Integer) value);
                break;                 
            }            
            fireTableCellUpdated(row, col);  
         }  
      
          
        @Override  
        public boolean isCellEditable(int rowIndex, int columnIndex){  
            /* Aqui voce indica qual coluna vai ser editável ou não, 
             Abaixo, somente a primeira coluna não é editável */  
            return false;  
        }  
      
        @Override  
        public Class getColumnClass(int column){  
            // Aqui voce indica qual tipo de dado é retornado nas colunas  
            switch (column){
                case 0:
                    return Integer.class;
                case 1:
                    return String.class;
                case 2:
                    return Integer.class;                  
            }             
            return Object.class;
        }  
      
        public List<Aluno> getDataSet(){  
           // Aqui voce retorna todo o conjunto de dados  
           return alunos;  
        }  
      
        @Override  
        public String getColumnName(int column){  
            // Aqui define os nomes da colunas  
            return col[column];  
        }  
      
        public Object[] getRow(int row) {  
             // Aqui voce retorna um linha de registro inteira.  
             return new Object[]{alunos.get(row).getCodUsuario(),
                                 alunos.get(row).getNome(),
                                 alunos.get(row).getMatricula()};  
        }  
      
        public void removeRow(int row) {  
             // Aqui voce remove uma linha específica  
             alunos.remove(row);  
             fireTableDataChanged();  
        }  
      
        public void addRow(Object[] row) {  
            // Aqui voce acrescenta uma linha com um conjunto de registros específico  
            fireTableDataChanged();  
        }  
      
        public void addEmptyRow(){  
            // Aqui voce acrescenta uma linha em branco  
            fireTableDataChanged();  
        }  
        
        public Aluno getObject(int linha){
            return alunos.get(linha);
        } 
}
fbl.lucas

ja vi outras duvidas sua e acho que na sua DAO você abre a sessão como abaixo, mas provavelmente esta se esquecendo que você ja abriu esta sessão e esqueceu de fecha-la com o session.close()

Jackye

Oi,
já olhei as classes do projeto e não vejo nenhuma sessão aberta.
comentei todas mas ainda assim, o erro persiste.

:cry:

fbl.lucas

Jackye:
Oi,
já olhei as classes do projeto e não vejo nenhuma sessão aberta.
comentei todas mas ainda assim, o erro persiste.

:cry:

Tem certeza que sempre que você esta chamando o openSession() em seguida você chama o session.close()?
Porque o erro diz que existem duas session abertas.

williamdasflores

Jackye,
Se puder posta as classes DAO listar e remover aluno

Jackye

Oi williamdasflores.

Eu tô usando o Hibernate.
E no meu projeto de duas classes:
GENERICHIBERNATEDAO:

package Persistencia;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {
    
    private Class<T> entidadePersistente;
    private Session sessao;
 
    public GenericHibernateDAO() {
        this.entidadePersistente = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
 
    @SuppressWarnings("unchecked")
    public void setSession(Session s) {
        this.sessao = s;
    }
 
    protected Session getSession() {
        if (sessao == null)
            sessao = HibernateUtil.getSessionFactory().openSession();
        else
            if (!sessao.isOpen())
                sessao = HibernateUtil.getSessionFactory().openSession();
        return sessao;
    }
 
    public Class<T> getEntidadePersistente() {
        return entidadePersistente;
    }
 
    //@SuppressWarnings("unchecked")
    @Override
    public T findById(ID id) {
        T entidade = (T) getSession().load(getEntidadePersistente(), id);
        return entidade;
    }
 
    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll() {      
        return findByCriteria();
    }
 
    @SuppressWarnings("unchecked")
    @Override
    public T salvar(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().save(entidade);
        transacao.commit();
        getSession().close(); 
        return entidade;
    }
 
    @Override
    public void remover(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().delete(entidade);
        transacao.commit();
        getSession().close(); 
    }
    
    @Override
    public void atualizar(T entidade) {
        Transaction transacao = getSession().beginTransaction();
        getSession().saveOrUpdate(entidade);
        transacao.commit();
        getSession().close(); 
    }    
 
    public void flush() {
        getSession().flush();
    }
 
    public void clear() {
        getSession().clear();
    }
 
    @SuppressWarnings("unchecked")
    protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getEntidadePersistente());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }    
}

GENERICDAO:

package Persistencia;

import java.io.Serializable;
import java.util.List;
public interface GenericDAO<T, ID extends Serializable> {
 
    T findById(ID id);
 
    List<T> findAll();
 
    T salvar(T entitade);
    
    void remover(T entidade);
    
    void atualizar(T entidade);
 
}

A maioria das classes DAO são assim:

package Persistencia;

import Dominio.Aluno;

public class AlunoDAO extends GenericHibernateDAO<Aluno, Integer> {
    public static AlunoDAO fabricaAlunoDAO(){
        return new AlunoDAO();
    }    
    
}

Tô listando a partir de uma classe que estende a AbstractTableModel.

MAs acredito que seja o que fbl.lucas disse:

Tem certeza que sempre que você esta chamando o openSession() em seguida você chama o session.close()?
Porque o erro diz que existem duas session abertas.

Vou analisar novamente, porque tenho alguns metodos na classe DAO Exemplar:

package Persistencia;

import Dominio.Exemplar;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.hibernate.Session;

public class ExemplarDAO extends GenericHibernateDAO<Exemplar, Integer> {

    public static ExemplarDAO fabricaExemplarDAO() {
        return new ExemplarDAO();
    }
    List<Exemplar> exemplares;

    
    public List<Exemplar> verificarIndisponivel(){
        Session sessao = HibernateUtil.getSessionFactory().openSession();
        List listaExemplarIndisponivel = new ArrayList();
        listaExemplarIndisponivel = sessao.getNamedQuery("Exemplar.findByIndisponivel").list();
        return listaExemplarIndisponivel;
    } 
    
   public void mudarStatusEmprestimo(int Codigo) {      
        Session session = HibernateUtil.getSessionFactory().openSession();      
        session.createQuery("UPDATE Exemplar set inEmprestimo = 1 where codExemplar = " + Codigo).executeUpdate(); 
    }  
}

:smiley:

fbl.lucas

Olha na sua ExemplarDAO nos métodos verificarIndisponivel() e mudarStatusEmprestimo() você abre a session sendo que na superclasse GenericHibernateDAO você tem um método getSession que ja realiza isso. Outra questão é que cada DAO sua que extende GenericHibernateDAO vai ter uma session própria, acredito que isso seja um problema também. Não tenho experiencia em programação desktop mas acredito que GenericHibernateDAO deveria ser assim:

public abstract class GenericHibernateDAO<T, ID extends Serializable>  
        implements GenericDAO<T, ID> {  
      
    private Class<T> entidadePersistente;  
    private static Session sessao;  
  
    public GenericHibernateDAO() {  
        this.entidadePersistente = (Class<T>) ((ParameterizedType) getClass()  
                                .getGenericSuperclass()).getActualTypeArguments()[0];  
    }  
  
    protected Session getSession() {  
        if (sessao == null || !sessao.isOpen())  {
               synchronized (this) {
			if (sessao == null || !sessao.isOpen())  
				sessao = HibernateUtil.getSessionFactory().openSession();
		}
        }
        return sessao;  
    }  
 ...

Desta forma você só terá acesso a session nas DAOs através no método getSession() que faz o controle se a session esta ou não aberta

williamdasflores

Acredito que seja isso mesmo que o nosso amigo fbl.lucas falou.
Nos métodos verificarIndisponivel e mudarStatusEmprestimo você não fechou a session.

Criado 16 de fevereiro de 2012
Ultima resposta 17 de fev. de 2012
Respostas 10
Participantes 4