try{
stmt = getCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(query);
CachedRowSet rowset = new CachedRowSetImpl();
rowset.populate(rs);
return rowset;
} finally {
if (stmt != null) stmt.close();
if (rs != null) rs.close();
}
}catch(SQLException e){
throw new RuntimeException(e);
}
} [/code]
Você só deve reduzir a intensidade da exception para uma Runtime ou para um Log simples se a tratou. No caso, o tratamento da exception envolve o fechamento dos Statements e do ResultSet. O ideal seria fechar a conexão também, usando para isso um Pool de conexões.
O seu primeiro caso relança a exception, mas deixando os recursos abertos e tirando do programador que recebe a exception a possibilidade de trata-la. Por isso também é inadequado.
Esse tratamento, com o Pool, não é tão trivial. Uma sugestão é baixar uma biblioteca que já faça esse tipo de método exatamente como você quer corretamente. Essa biblioteca é o Spring.
Outra coisa. Nunca faça catch em “Exception”. Como o código tratado só irá lançar uma SQLException, é bom dar o catch nela.
Aí se eventualmente uma RuntimeException inesperada de outro tipo for lançada, você não irá empacota-la na RuntimeException que trata de SQLExceptions, deixando o StackTrace final mais simples.
RuntimeException são exceções que não precisam ser capturadas com um try catch. Por isso o meu código ali converte a SQLException lançada numa RuntimeException. Note que não tem throws para aquela runtime que lanço.
Se você der um catch em Exception, você vai capturar tanto as SQLExceptions, como outras exceptions que os método lançarem, incluindo eventuais RuntimeExceptions. Por exemplo, vamos supor que o método executeQuery do ResultSet, por um erro de programação do driver, lance uma IndexOutOfBoundsException.
Isso não é uma SQLException, mas não precisou ser pega no try…catch por ser uma RuntimeException. O seu catch com Exception iria captura-la, um catch com SQLException não.