(otimização no java)Problema muito estranho com ResultSet fechado do postgresql

Olá :slight_smile:
Estou com um probleminha muitoooo estranho :frowning: . Já executei métodos parecidos com o abaixo e funcionam, mas com esse não :C
não sei porque =/. Lembrando que cada vez que eu executo um método de uma classe, após não ter nenhum método mais daquela classe para ser executado eu chamo o método “fechaconexao()”, que citei ali embaixo. Só que quando executo este método(select_link) acusa o erro de ResultSet fechado.

Alguém tem um sugestão de como arrumar isso ou outra alternativa?
Já tentei abrir uma conexão para cada método de uma classe, porém fica muito lento no meu bando de dados, eu teria que ter uma conexão para cada classe no máximo.

Obrigado \o.

Tenho um método que chama:

link_ctrl lic = new link_ctrl(); ResultSet rs = lic.select_link("NULL");
(o rs acusa erro de result set fechado)

[code]class link_ctrl {
String SQL;
Conexao conex;
Connection con = null;
Statement stm = null;
ResultSet rs = null;

public link_in_ctrl() {
	conex = new Conexao();
	try {
		con = conex.getConexao();
	} catch (SQLException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
	try {
		stm = con.createStatement();
	} catch (SQLException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
}

public ResultSet select_link(String root_url) {
ResultSet rs = null;
SQL = "SELECT idlink,url_complete FROM link where root_url is "
+ root_url + “”;
try {
rs = stm.executeQuery(SQL);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

	return rs;
}
public void fechaconexao() {
	try {
		conex.destroyConnection(con);
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

}
[/code]

[code]class Conexao {
final static String DRIVER_POSTGRES = “org.postgresql.Driver”;
final static String URL_POSTGRES = “jdbc:postgresql://localhost:5432/teste?&user=a&password=a”;
final static String NOME_USUARIO = “a”;
final static String SENHA_USUARIO = “a”;

public Conexao() {
	try {
		Class.forName(DRIVER_POSTGRES);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

public Connection getConexao() throws SQLException {
	Connection c = DriverManager.getConnection(URL_POSTGRES);
	return (c);
}

public void destroyConnection(Connection con) throws SQLException {
	try {
		con.close();
	} catch (SQLException r) {
		System.out.println(" Erro-100C Conexao nao estabelecida...");
	}

}

}
[/code]

por eu estar criando um objeto novo e uma nova conexão por causa da classe que instancio, não deveria dar este problema né?._.

Olá,

Coloca a tag code no seu código para que seja possível entendê-lo. Do jeito que está fica impraticável a leitura.

http://www.guj.com.br/posts/list/50115.java

[]s
Éberson

pronto

Cara, seria melhor se postasse o trecho do código em que vc faz a chamada mas, estou postando um teste que eu fiz:
Connection:


package teste_guj;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *
 * @author gabriel.arcanjo
 */
public class ConnectionFactory {
   private static String driver = "org.postgresql.Driver";

  private static String URL = "jdbc:postgresql://localhost:5432/postgres";//Vc tem que colocar o nome do seu banco. Vc coloca o localhost se o MySql estive na mesma maquina da aplicação, se não vc tem que colocar o ip do servidor de Dados.

  private static String USE = "root";// Geralmente é root a não ser que vc mude

  private static String SENHA = "senha";//seu senha


    public static Connection getConnection() throws ClassNotFoundException, SQLException{
        Class.forName(driver);
        return DriverManager.getConnection(URL, USE, SENHA);

    }
    public static void closeConnection(Connection conn, Statement stmt, ResultSet rs){
    close(conn, stmt, rs);
    }
     public static void closeConnection(Connection conn, Statement stmt){
    close(conn, stmt, null);
    }
      public static void closeConnection(Connection conn){
    close(conn, null, null);
    }

    private static void close(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (rs !=null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
        }
    }

}

Utilização:

package teste_guj;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author gabriel.arcanjo
 */
public class Main {

    static Connection conn;
    static Statement stmt;
    static ResultSet rs;

    public static void main(String[] args) {
        try {
            conn = ConnectionFactory.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT * FROM agente_negocio");
            while (rs.next()) {
                System.out.println("Nome->" + rs.getString("nome_fantasia"));
            }
            ConnectionFactory.closeConnection(conn, stmt, rs);


            conn = ConnectionFactory.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT * FROM agente_negocio");
            while (rs.next()) {
                System.out.println("Nome->" + rs.getString("nome_fantasia"));
            }
            ConnectionFactory.closeConnection(conn, stmt, rs);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Lembre sempre, sempre fechar a conexão.

ah sim claro,
mas meu problema é otimização. Não posso ficar criando uma conexão para cada método meu, porque isso deixa meu programa lento(abrindo e fechando conexão toda hora). Meu problema ali é tentar não criar a conexão em cada método, apenas no início da classe e utilizar para todos os métodos daquela classe, porém da resultset fechado.

Então feche apenas o ResulSet como segue no código:

package teste_guj;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author gabriel.arcanjo
 */
public class Main {

    static Connection conn;
    static Statement stmt;
    static ResultSet rs;

    public static void main(String[] args) {
        try {
            conn = ConnectionFactory.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT * FROM agente_negocio");
            while (rs.next()) {
                System.out.println("Nome->" + rs.getString("nome_fantasia"));
            }
            ConnectionFactory.closeConnection(null, null, rs);


//            conn = ConnectionFactory.getConnection();
//            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT * FROM agente_negocio");
            while (rs.next()) {
                System.out.println("Nome->" + rs.getString("nome_fantasia"));
            }
            ConnectionFactory.closeConnection(conn, stmt, rs);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

mas aí tenho outro problema :slight_smile:
o postgres tem um máximo de conexões simultâneas. Não posso ficar só abrindo e fechando apenas o resultset.
O que eu estava fazendo:

Instancio uma classe controle que abre uma conexão
Utilizo os métodos dela e fecho a conexão
Quando vou instanciar outra classe controle(conforme postei no primeiro post) e crio uma nova conexão, da resultset fechado.

Bem, tenta criar a classe de conexão estática.
Pode também tentar criar um pool de conexão.

como seria a classe de conexão estática? apenas os métodos que chamam a conexão serem estáticos?

Você poderia implementar um sigleton. Algo assim:

[code]public class ConnectionFactory {
private static Connection connection;

public static Connection getConnection() throws ClassNotFoundException, SQLException{
Class.forName(“org.postgresql.Driver”);

  if ( connection == null ){
     String URL = "jdbc:postgresql://localhost:5432/postgres";  
     String USE = "root";
     String SENHA = "senha";

     connection = DriverManager.getConnection(URL, USE, SENHA);
  }

  return connection;

}
}[/code]

Assim você consegue garantir que só vai existir uma instância dessa conexão na sua aplicação e irá abrí-la apenas um vez (quando for realmente usá-la).

Se ainda assim o problema do ResultSet persistir, forneça mais informações para que possamos avaliar a situação.

[]s
Éberson

Como voce esta usando jdbc ate onde eu lembro a sua lentidao ta devido a sempre instancia uma nova conexão…
o que da problema geralmente e que ninguem sabe o porque …é usar o mesmo statement pra diferentes resultset…
principalmente com 1 dentro do outro…
talvez esteja ai seu problema dele falar que o resultset ja está fechado.

teoricamente voce precisa usar apenas 1 conexão(seja ela o singleton ou não)…
singleton ajuda pois pode ser que outra pessoa pegue a conexão ja aberta o que consome menos recurso de instanciação…
pra cada resultset use seu proprio statement…quando for trabalhar com resultset dentro de resultset…
e feche a conexão no fim…