[RESOLVIDA]Problema em conectar com o Banco

Tenho uma tela que cuida do cadastro de docente, após a inserção das informações o usuário clica no botão “Salvar”. No código do actionPerformed do botão “Salvar” é onde passo os dados para a classe de docente e em uma outra classe, que é a que conecta o JAVA com o PostgreSQL, eu pego os dados da classe docente e passo pro banco, na primeira execução as coisas rodam de boa, mas a partir da segunda vez aparece um erro que diz “This connection has been closed.” a conexão foi fechada, ainda não entendo muito bem sobre fechar e abrir a conexão aí não tô sabendo identificar o erro.
Uso o eclipse e o postgres. Segue o código que o eclipse acusou de erro.

Código do botão Salvar:

btnSalvar.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent arg0) {
				
		docente.setNome(tfNome.getText());
		docente.setPseudo(tfPseudo.getText());
		docente.setCelular(tfCelular.getText());
		docente.setEmail(tfEmail.getText());
				
		if(rdbtn20h.isSelected()) {
			docente.setRegime("20h");
		}else if(rdbtn40h.isSelected()) {
			docente.setRegime("40h");
		}else if(rdbtn40hDE.isSelected()) {
			docente.setRegime("40hDE");
		}
				
				
		String selecao = (String) (cbCoordenadoria.getSelectedItem());
				
		ResultSet rs1 = inserir.executarBusca("select CoordCod from coordenadoria where CoordSigla = '"+selecao+"';");//Retorna o codigo da coordenadooria
				
				
		try {
					
			while(rs1.next()) {
				docente.setCoordenadoria(rs1.getInt("CoordCod"));//Passa o codigo da coordenadoria para classe Docente
			}
					
			if(rdbtnDisponivel.isSelected()) {
				docente.setStatus("Disponível");
			}else if(rdbtnIndisponivel.isSelected()) {
				docente.setStatus("Indisponível");
			}else if(rdbtnSemidisponivel.isSelected()) {
				docente.setStatus("SemiDisponível");
				if((String)(cbCargo.getSelectedItem())=="Coordenador(a)") {
							
					String selecao1 = (String) (cbCoordenadoria.getSelectedItem());
							
					ResultSet res4 = inserir.executarBusca("select CoordCod from coordenadoria where CoordSigla = '"+selecao1+"'");
							
					while(res4.next()) {
						docente.setCoordenadoria(res4.getInt("CoordCod"));
					}
							
							
					String selecao2 = (String) (cbCoordenador.getSelectedItem());
							
					ResultSet res2 = inserir.executarBusca("select CoordCod from coordenadoria where CoordSigla = '"+selecao2+"'");
					ResultSet res3 = inserir.executarBusca("select DocCod from docente where DocNome = '"+tfNome.getText()+"'");
							
					while(res2.next()){
						coord.setCoordCod(res2.getInt("CoordCod"));
					}
							
					while(res3.next()){
						docente.setDocCod(res3.getInt("DocCod"));
					}
							
					inserir.coordenadorUpdate(docente,coord);//Faz o Update na tabela de coordenadoria, passando o código de docente.
					cbCoordenador.removeItem(selecao2);//Remove do comboBox a coordenadoria que teve seu coordenador cadastrado.
			
				}	
			}
					
			inserir.inserir(docente);
					
			} catch (Exception e) {
				e.printStackTrace();
			}
			JOptionPane.showMessageDialog(null, "Cadastro realizado com sucesso.");
				
		}
	});

Código do inserir.executarBusca(sql);

public ResultSet executarBusca(String sql){
	try {
		PreparedStatement stm = con.prepareStatement(sql);
		ResultSet rs = stm.executeQuery();
			
		return rs;
	} catch (Exception e) {
		e.printStackTrace();
		return null;
	}
}

Código do inserir.inserir(docente);

public void inserir(CLASSDocente docente) {
		
	try {
			
			
		String sql = "insert into docente (DocCod,DocNome,DocPseudo,DocRegime,DocEmail,DocCelular,DocStatus,CoordCod,DocCargo)\r\n" + 
					 "values (default,?,?,?,?,?,?,?,?);";
			
		PreparedStatement stm = con.prepareStatement(sql);
			
		stm.setString(1, docente.getNome());
		stm.setString(2, docente.getPseudo());
		stm.setString(3, docente.getRegime());
		stm.setString(4, docente.getEmail());
		stm.setString(5, docente.getCelular());
		stm.setString(6, docente.getStatus());
		stm.setInt(7, docente.getCoordenadoria());
		stm.setString(8, docente.getCargo());
			
		stm.executeUpdate();
		stm.close();
		con.close();
			
	} catch (Exception e) {
		e.printStackTrace();
	}
}

Não vejo necessidade de fechar a conexão, porquê pra tudo que você precisar fazer que envolva manipulação dos dados, você vai precisar ficar criando e fechando conexão, e isso é bem custoso pra uma aplicação, mas se quiser manter dessa forma tu tem que abrir a conexão novamente antes de iniciar o processo todo.

@Jonathan_Medeiros Mas não dá problema não? Se não fechar a conexão?

Abrir a conexão. Achei que era isso que eu tava fazendo aqui:

private Connection con;
	
public INSERTDocente() {
	this.con = new ConexaoUtil().getConnection();
}

E aí usando o con eu estaria abrindo a conexão.

Depende de caso para caso, tudo tem que ser avaliado, mas 99.9% dos casos isso não tem problema!
Inclusive eu mesmo nunca presenciei um caso em que fosse necessário ficar abrindo e fechando conexão com a base de dados!

Abrir a conexão acredito que é exatamente isso que o código que colocou em resposta está fazendo!
Porém ele está no devido lugar? Se você for manter este padrão a abertura da conexão deve ocorrer antes de qualquer outra operação, e no seu código de salvar, não é isso que está acontecendo!

@Jonathan_Medeiros É você tinha razão. Tirei a linha de código que fechava a conexão e funcionou.
Como não é algo comum dar problema com a conexão aberta então deixarei assim sem fechar mesmo kkkkkk valeu cara.

O problema pode acontecer se vc abrir varias conexões com o banco e não fechar, ai vai ter uma hora que vai dar erro de ter muitas conexões abertas!!

1 curtida

@rodriguesabner Vish, serio? Como eu tô fazendo não tá abrindo a conexão em cada método né?
O código tá assim:

public class INSERTDocente {
	
	private Connection con;
	
	public INSERTDocente() {
		this.con = new ConexaoUtil().getConnection();
	}
	
	public void inserir(CLASSDocente docente) {
		
		try {
			
			String sql = "insert into docente (DocCod,DocNome,DocPseudo,DocRegime,DocEmail,DocCelular,DocStatus,CoordCod,DocCargo)\r\n" + 
						 "values (default,?,?,?,?,?,?,?,?);";
			
			PreparedStatement stm = con.prepareStatement(sql);
			
			stm.setString(1, docente.getNome());
			stm.setString(2, docente.getPseudo());
			stm.setString(3, docente.getRegime());
			stm.setString(4, docente.getEmail());
			stm.setString(5, docente.getCelular());
			stm.setString(6, docente.getStatus());
			stm.setInt(7, docente.getCoordenadoria());
			stm.setString(8, docente.getCargo());
			
			
			
			
			stm.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public ResultSet executarBusca(String sql){
		try {
			PreparedStatement stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			
			return rs;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	
	public void coordenadorUpdate(CLASSDocente docente, CLASSCoord coord) {
		
		
		try {
			
			String sql = "update coordenadoria set DocCod = ? from docente where docente.DocCod = ? and coordenadoria.CoordCod = ?;";
			PreparedStatement stm = con.prepareStatement(sql);
			
			stm.setInt(1, docente.getDocCod());
			stm.setInt(2, docente.getDocCod());
			stm.setInt(3, coord.getCoordCod());
			
			stm.executeUpdate();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void dadoUpdate(CLASSDocente doc, String nome) {
		
		
		try {
			
			Statement stm = con.createStatement(); 
			String sql = "update docente set DocNome='"+doc.getNome()+"', DocPseudo='"+doc.getPseudo()+"', DocRegime='"+doc.getRegime()+"', DocEmail='"+doc.getEmail()+"', DocCelular='"+doc.getCelular()+"', DocStatus='"+doc.getStatus()+"', DocCargo='"+doc.getCargo()+"', CoordCod="+doc.getCoordenadoria()+" where DocNome = '"+nome+"'";
			
			stm.executeUpdate(sql);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Código da ConexaoUtil:

public class ConexaoUtil {
		
	private String url;
	private String usuario;
	private String senha;
	private Connection con;
	
	public Connection getConnection(){
		
		try{
			url = "jdbc:postgresql://localhost:5432/Horario";
			usuario= "postgres";
			senha= "postgres";
		
			return DriverManager.getConnection(url,usuario,senha);
		
		}catch(SQLException e){
			throw new RuntimeException(e);
		}
		
	}
}

Ao invés de criar a conexão em toda classe, faça a sua classe de conexão fazer esse trabalho!

Algo mais ou menos assim:

public class ConexaoUtil {

    private static ConexaoUtil instance;
    private Connection connection;
    private final String url = "jdbc:postgresql://localhost:5432/Horario";
    private final String usuario = "postgres";
    private final String senha = "postgres";

    private ConexaoUtil() {
        try {            
            this.connection = DriverManager.getConnection(this.url, this.usuario, this.senha);
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
    }

    public Connection getConnection() {
        return this.connection;
    }

    public static ConexaoUtil getInstance() throws SQLException {
        if (instance == null) {
            instance = new ConexaoUtil();
        } else if (instance.getConnection().isClosed()) {
            instance = new ConexaoUtil();
        }

        return instance;
    }
}
1 curtida

@Jonathan_Medeiros Assim?

public class ConexaoUtil {
	    
	private final String url = "jdbc:postgresql://localhost:5432/Horario";
	private final String usuario= "postgres";
	private final String senha= "postgres";
	private static Connection instance = null;
	    
	private ConexaoUtil() {
		try {
			this.instance = DriverManager.getConnection(this.url, this.usuario, this.senha);
		} catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	    
	public static Connection getInstance() {
		if (instance == null) {
			instance = (Connection) new ConexaoUtil();
		}
	        
		return instance;
	}
}

Editei a resposta anterior, observando com um pouco mais de atenção eu tinha digitado o código de forma incorreta.

1 curtida

@Jonathan_Medeiros Tem razão, estava de forma incorreta. Então, tive que mudar a visibilidade da ConexaoUtil de private para public, se não as classe de INSERT que são as classes que executam os SQLs não teriam acesso.
Então desse jeito que você me passou, como eu chamo essa classe? E tenho que chamar ela toda vez que quiser usar a conexão? E não preciso fechar ela?

@Jonathan_Medeiros Deu certo!! Usa do jeito que imaginei mesmo, valeu mesmo cara, me salvou kkkkk

O atributo é privado pra não ter acesso direto ao atributo!

O uso se dá da seguinte forma:

Connection con = ConexaoUtil.getInstance().getConnection();

1 curtida