Olá amigos, possuo o seguinte código que faz uma simples busca do banco de dados:
quando faço a busca ela vem correta e tal trazendo os dados, porém ela só faz isso se eu não usar o next(), se eu usar da erro dizendo q nao possui mais registros, ou seja, o registro q busco está na posição 0 do resultset!
Alguém tem uma explicação pra isso?
porque até onde eu sei é sempre necessário usar o next para acessar o primeiro registro.
Agradeço a atenção.
public boolean verifyUserGrants(String user, String pass,
boolean isAdministrator) {
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = this.connection.prepareStatement("SELECT * FROM users WHERE userName = ? AND password = ?");
statement.setString(1, user);
statement.setString(2, pass);
rs = statement.executeQuery();
if (rs.next()) {
if (isAdministrator) {
String role = rs.getString("role");
if (role.equals("1")){
return true;
}else{
return false;
}
}
return true;
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}finally{
try {
if (rs != null)
rs.close();
if (statement != null)
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Quantos registros a query retorna?
Devem existir registros duplicados, rode a query direto no seu banco de dados, para evitar esse problema vc não deve permitir o cadastro de usuários duplicados, vc consegue trazer somente 1 registro alterando a propria query por exemplo:
Postgres ou Mysql
select campo from tabela limit 1
SQL Server
select campo from tabela top 1
Cada banco de dados tem a sua sintaxe da limitação.
Retorna só um registro, é o único do banco.
Qual a mensagem de erro que gera?
Troque o if(rs.next()) por um while(rs.next()) e veja se funciona.
Valeu a resposta pedrosa, não aparece mensagem de erro pq o next está no if e retorna false, mas seria um erro comum de nao possuir mais registros.
Com while é o mesmo problema, só não consigo entender o pq de acontecer isso no next().
Coloca a printStackTrace, isto não deveria ocorrer, antes de usar os métodos rs é obrigatório usar o rs.next(), indiferente de usar if ou while que server para verificar se tem registro e não dar erro.
Inicialmente ele aponta para uma posição inválida, dai o uso do método rs.next() que atualiza a posição do cursor para uma posição válida e a sequência de registro.
Tirei o next de dentro do if para mostrar o stacktrace:
Error: After end of result set
java.sql.SQLException: After end of result set
at com.mysql.jdbc.ResultSet.checkRowPos(ResultSet.java:3624)
at com.mysql.jdbc.ResultSet.getString(ResultSet.java:1758)
at com.mysql.jdbc.ResultSet.getString(ResultSet.java:1822)
at pucrs.caselearn.dao.jdbcDaoImpl.DAOUser.verifyUserGrants(DAOUser.java:48)
at pucrs.caselearn.user.UserLogon.doPost(UserLogon.java:41)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
jonatanpedro,
Você tem que usar o ResultSet .next(), se for um registro você usa o if se for vários usa o while
if(rs.next()){
String role = rs.getString("role");
}
Pela mensagem de erro é como se você tivesse percorrido todos os registros e depois tentar acessar o método do ResultSet, mas como já percorreu todos os registros não dá mais para acessar os métodos para recuperar os valores do registro.
O campo role existe?
Sua consulta retorna 1 registro se o usuário e senha baterem, e 0 registros se alguma coisa não bater (usuário e/ou senha).
Quando entramos dentro do if (next), então você já sabe que o usuário e a senha batem, e existe o tal usuário no banco.
Se não entrar no if (next), então o usuário e/ou senha não bateram, então você tem de retornar false mesmo. Simples assim.
[color=darkblue]existe um problema…
vc declarou return dentro da condição de verificação… se vc for usar tanto if quanto while, se for valida a condição, ele já dá return, então ele sai da expressão…
Não tenho certeza… mas acho q é isso…[/color]
Obrigado a todos pelas respostas, mas o problema era algum bug da virtual machine, ou algo do genero, aquele código não era meu, então resolvi apagá-lo e reescrever um e funcionou.
