Estou o obtendo o erro The result set is closed no código abaixo:
public List retornaCategorias() throws Exception {
Statement stmt = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
ResultSet rsImagem = null;
try {
String sb = null;
String comandoSQL = null;
sb = "select * from grupo where not (nome_grupo is null) order by nome_grupo desc ";
comandoSQL = "select count(*) as total from produto where cp_grupo = ? and ( not cp_imgprod is null)";
stmt = conn.createStatement();
pstmt = conn.prepareStatement(comandoSQL);
rset = stmt.executeQuery(sb);
List<Categoria> categorias = new ArrayList<Categoria>();
Categoria umaCategoria;
while (rset.next()) {
umaCategoria = new Categoria();
umaCategoria.setDescricao(rset.getString("nome_grupo"));
umaCategoria.setId(rset.getInt("cp_grupo"));
pstmt.setInt(1,umaCategoria.getId());
rsImagem = pstmt.executeQuery();
if (rsImagem.next()) {
if (rsImagem.getInt("total") > 0) {
categorias.add(umaCategoria);
}
}
}
return categorias;
} finally {
if (rset != null) try { rset.close(); } catch(Exception e) { }
if (stmt != null) try { stmt.close(); } catch(Exception e) { }
}
}
este erro acontece na segunda iteração do loop mais externo. precisamente na linha while (rset.next())
Nesse código, abro um resultset e com dados desse abro outro aninhadamente…
Parece que quando ele chega ao fim do resultset interno ele fecha o primeiro!
Será que eu teria que usar uma connection para cada resultset?
Pelo erro que você mencionou, parece que você já está fazendo isso. Sendo assim dá uma olhada se suas queries estão corretas e se estáo retornando valores ou não.
Mas uma coisa, prefira usar somente o PreparedStatement ao invés do Statement.
Tenta ir depurando o código parte por parte para ver onde está o problema. Vc pode depurar usando um depurador mesmo, ou então ir removendo algumas linhas de código para achar onde está enroscando.
Já vi este erro acontecer quando o result set vem vazio e vc tenta dar o next(), por isso falei para vc ver se as queries (a externa) está correta.
Os dois selects estão ok, já os testei com a ferramenta isql do banco. Pesquisando na web, li em algum lugar que esse problema parece ser do driver jdbc e/ou banco.
Cara, eu custo acreditar que esse tipo de problema possa ocorrer num código super comum (Processar uma lista dentro da outra). Eu faço isso corriqueiramente, todos os dias com delphi…
Deve haver algum mecanismo, parametro para aqueles prepareStatement para isso ser possível…
vou pesquisar mais… se souber de algo nesse sentido posta ai pra nós…
não faz sentido usar preparedStatement repetidamente dentro de loops, já que a idéia é preparar a sua query uma única vez no bd e usá “compilada” passando somente seus parametros… . Do jeito que vc sugeriu não funcionou, mas de qualquer forma obrigado a todos que se empenharam em ajudar…
Consegui resolver o meu problema usando a interface CachedRowSet. A implementação dessa interface gera um rowset desconectado do banco o que permite que vc itere pelo mesmo sem ser afetado pelas operações de resultsets internos ao loop. Além do mais ele possui cursores pra frente e para traz dando maior flexibilidade para se trabalhar em algoritmos.
public List retornaCategorias() throws Exception {
Statement stmt = null;
PreparedStatement pstmt = null;
ResultSet rsImagem = null;
ResultSet rset;
try {
String comandoSQLCached = null;
String comandoSQL = null;
comandoSQLCached = "select * from grupo where not nome_grupo is null order by nome_grupo";
comandoSQL = "select count(*) as total from produto where cp_grupo = ? and ( not cp_imgprod is null) ";
stmt = conn.createStatement(); // prepara o statement da query
rset = stmt.executeQuery(comandoSQLCached); // executa a query
CachedRowSet crs = new CachedRowSetImpl(); // cria o CachedRowSet
crs.populate(rset); // preenche com dados do resultado da query
pstmt = conn.prepareStatement(comandoSQL); // prepara p statement parametrizado
List categorias = new ArrayList(); // cria a lista a ser populada
Categoria umaCategoria; // item da lista
while (crs.next()) { // itera pelo CachedRowSet
umaCategoria = new Categoria();
umaCategoria.setDescricao(crs.getString("nome_grupo"));
umaCategoria.setId(crs.getInt("cp_grupo"));
pstmt.setInt(1,umaCategoria.getId());
rsImagem = pstmt.executeQuery();
if (rsImagem != null) {
if (rsImagem.next()) {
if ((rsImagem.getInt("total") > 0)) {
categorias.add(umaCategoria);
}
}
}
}
return categorias;
} finally {
if (rset != null) try { rset.close(); } catch(Exception e) { }
if (stmt != null) try { stmt.close(); } catch(Exception e) { }
if (pstmt != null) try { pstmt.close(); } catch(Exception e) { }
}
}
Nos testes que fiz não detectei nenhuma perda de performance.