Duvida com fechamento de statement e resultSet

Galeraa…

Eu tenho um pacote com varias classes q acessam o banco de dados…
E cada metodo tem o seguinte no fim:

finally{ try{ BD.resultSet.close(); BD.statement.close(); catch(SQLException e){ e.printStackTrace(); } }

soh q isso esta fechando a conexao com o banco…nao sei pq rsrs

alguem pode dar uma ajuda!?

Desde já agradeço!

coloca o stmt.close() após o retorno do metodo que estiver chamando… faz um teste.

continua dando o mesmo erro…

e o pior eh q esse erro nao acontece toda hora…ele acontece de vez enquando…
e soh em 2 metodos q sao chamados por uma thread…

sera q tem algo haver isso?

e quando da o erro ele seta nesse comando:

BD.setResultSet(sql);

segue o metodo do setResultSet

public static void setResultSet(String sql) throws SQLException{ if(status==false){ BD.getConnection(); } statement= connection.createStatement(); resultSet= statement.executeQuery(sql); }

ele da nullPointerException…

Mas a string sql q eu passo pra ele tem valor q eu jah conferi :S

corrigindo…

Eu testei aqui e ele nao fecha a conexão naoo…ela continua “ligada”…

ele da a seguinte exception:

java.lang.NullPointerException at com.mysql.jdbc.StatementImpl.useServerFetch(StatementImpl.java:2567) at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1353) at metodos.BD.setResultSet(BD.java:103) at beansDb.PendenciaDb.getPendenciasAtivas(PendenciaDb.java:218) at metodos.ThreadVerificaPendencia.run(ThreadVerificaPendencia.java:26) at java.lang.Thread.run(Thread.java:619)

e ele seta essa linha na classe do banco:

resultSet= statement.executeQuery(sql);

e tambem no metodo seta essa linha:

BD.setResultSet(sql);

O finally em si está certo.

Mas outras coisas nesse código cheiram a POG, e dos feios.

O resultset e o statement não deveriam ser propriedades da classe BD, muito menos públicas. É necessário criar um Statement diferente por thread. E é também recomendável fechar a conexão no finally.

Como a conexão é um recurso demorado de ser obtido, o ideal é também usar o apache DBCP ou o C3P0 para fazer um pool de conexões.

Do jeito que está, ambas as threads compartilham o mesmo resultset e statement. Sem falar que as propriedades estão excessivamente permissivas, permitindo, por exemplo, que um programador as defina para null.

putss…era isso mesmo :S

Vlw pela ajuda ae emm!!!

Abraços!

mas ja que você (Vini) chegou a esse assunto…rs

como seria a forma correta de criar os statments, resultSets e a propria conexão com o banco!?

eh necessário cada vez q eu for fazer uma consulta, inserção, exclusão, alteração, etc., no banco eu tenho q criar um novo resultSet!?

Desde já agradeço!

Ta meio estranho mesmo isso…

Como já foi dito, em uma situação de concorrência sua classe vai dar pau - ai você lasca um syncronized e perde a vantagem do paralelistmo.

Mas o que está mais estranho é a classe TER uma instância de ResultSet, e se outra Thread mandar executar o método setResultSet quando uma outra thread ainda está lendo os resultados anteriores?

Melhor você rever algumas questões de desenho desta classe.

Dê uma olhada no DBUtils da apache: http://commons.apache.org/dbutils/examples.html

Veja como é feito, eu acho show de bola aquilo ali. :smiley:

entaoo…para isso eu fiz um Gambiarra suahsuahsuahsa…
pq esse projeto ja ta muito adiantado…e ai eu preciso terminar ele logo…e depois quando tiver mais tempo eu volto pra consertar algumas coisas rsrs…

pq o q eu fiz pra consertar foi o seguinte:

eu criei 3 resultSets, 3 statements e 3 metodos setResultSet…

aiii…qualqer operação eu mando pra o resultSet1…uma thread vai no setResultSet2, e a outra thread vai para o setRresultSet3…

eh uma puta gambiarra…mas por enquanto vo te q dexa assim rsrs…
depois eu volto pra consertar…rsrs

Égua mah, faz isso não bixo, depois vai dar problemas e o culpado, é você!
Diz que precisa de mais tempo e pronto.

entaoo…mas se eu for concertar eu teria q fazer o q exatamente?

o meu metodo setResultSet alem de receber a sql teria q receber tmbm o resultSet e o statement?

eu criei o seguinte metodo na classe do banco:

public static ResultSet setResultSet(ResultSet rs, Statement st, String sql) { try { st= connection.createStatement(); rs= st.executeQuery(sql); status = true; } catch(Exception e){ new StackTrace(e, sql, "setResultSet"); } return rs; }

e ae eu chamo ele no metodo assim:

[code]ResultSet rs = null;
Statement st = null;

try
{
rs = BD.setResultSet(rs, st, “SELECT * FROM usuario WHERE usuario=’”+usuario+"’ AND senha=’"+senha+"’");
rs.next();
if (rs.getRow()>0)
{
if(rs.getString(“status”).equals(“1”)){
res = “0”;
}
else{
Geral.usuario = new Usuario(rs.getInt(“id_usuario”), rs.getString(“nome_usu”),rs.getShort(“admin”),rs.getString(“configuracao”), rs.getInt(“status”));
res = “1”;
}
}
catch(Exception e){
e.printStackTrace();
}[/code]

esta eh a forma correta?

ou eu nem precise do metodo setResultSet?

fazendo da seguinte forma:

[code]Statement st = null;
ResultSet rs = null;

	String res = "2";
	try
	{
		st = BD.connection.createStatement();
		rs = st.executeQuery("SELECT * FROM usuario WHERE usuario='"+usuario+"' AND senha='"+senha+"'");
		
		rs.next();[/code]

qual eh a maneira correta?

Shoker, na boa!

Acho que vc construiu uma “arapuca” e está pulando para dentro com tudo.

Se o código da classe BD não for muito grande tente inclui-la em um post para a galera dar uma olhada e tentar construir uma solução mais segura e mais organizada pra te ajudar.

flws

a classe bd soh tem os metodos getConnection, setResultSet, runSQL e close.

Mas eu qeria sabe se na hora q eu for fazer um setResultSet seria melhor ao invez de eu chamar o metodo eu fazer o seguinte:

ex:

public Metodo(){
  Statement st = null;
  ResultSet rs = null;
  String sql = "";
  
  try{
    st = BD2.connection.createStatement();
    sql = "sql aqui";
    rs = st.executeQuery(sql);  
    //continua...
  }
  catch(Exception e){
    //tratamento
  }
}

Pelo jeito a classe BD é pequena, porem tem muita coisa nela que parece não estar muito bem. O controle da conexão é um exemplo.

Já deu uma olhada na DbUtils indicada pelo camarada anteriormente? Parece uma boa idéia.

P.S Inclua o código da classe BD em um post pelo menos pra gente te falar os problemas.

flws

Não é correta. Se você incluir a palavra “static”, dificilmente estará usando a forma correta.
Infelizmente, não é tão trivial te explicar como é a forma correta.

Entretanto, para uma correção simples no seu código essa forma está adequada. Só marque esse método também como synchronized para que duas threads não tentem acessa-lo ao mesmo tempo.