Consulta não entra no "while(rs.next)"

Olá!

Estou fazendo uma aplicação desktop como trabalho de conclusão de curso e estou com um problema interessante em um dos métodos de pesquisa. Ele funcionaria assim: tenho uma tela de cadastro de empresas com um campo na qual o usuário digita uma letra qualquer, o método de busca é disparado e ele deveria retornar os nomes das empresas que começam com aquela letra para um comboBox. Mas, ao passar pela classe DAO, ele indica que selecionou todas as empresas com sucesso mas não chega a entrar no laço para inserção dos dados em uma ArrayList!!

Alguém tem alguma ideia? Abaixo colocarei os códigos :smiley:

Na Classe DAO eu tenho isso

public ArrayList<Empresa> selectEmpresaTrechoNome(string nomeFantasia){
        ArrayList<Empresa> listaEmpresas = new ArrayList<>();
        System.out.println("Passei aqui com Nome Fantasia ---> " +nomeFantasia);
        try{
            Connection con = conn.getConexao();
            String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE '"+nomeFantasia+"%'";
            PreparedStatement pstmt = con.prepareStatment(sql);
            System.out.println("Passei aqui  " +sql);
            ResultSet rs = pstmt.executeQuery();
            boolean found = rs.next();
            System.out.println("Passei aqui  antes do while"); // Até aqui ele me mostra na tela. Depois ignora o while e vai p/ mensagem de que conseguiu selecionar
            while(rs.next){
                System.out.println("Passei aqui  while");
                 if(found){
                       System.out.println("Passei aqui IF ");
                    Empresa iEmp = new Empresa();
                     
                    iEmp.setCodigo(rs.getInt("CODIGO"));
                    iEmp.setRazaoSocial(rs.getString("RAZAOSOCIAL"));
                    iEmp.setNomeFantasia(rs.getString("NOMEFANTASIA"));
                    //aqui vem mais uns 17 campos! Estou fazendo a mão, então não vou copiar tudo
                    listaEmpresas.add(iEmp);
               }  
            }
        }catch(Exception e){
                 System.out.println("Problemas ao selecionas todas as empresas "+e);
        } return listaEmpresa
}

Na tela de cadastro de Empresa

//Isso preenche meu combo
public void carregaComboEmpresas(ArrayList<Empresa>al){
          for(int i=0; i<al.size();i++){
                 comboEmpresa.addItem(al.get(i).getNomeFantasia());
          }
}

/*Isso dispara o evento para buscar minhas empresas. É o método Key Released (já tentei key pressed) para pegar a letra digitada e jogar naquele método acima*/

private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){
            this.trechoNome = (txtPesquisa.getText());

            IEmpresa iEmp = new Empresa DAO(); 

            listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO
            carregaComboEmpresas(listaEmpresas);

}

Alguém tem alguma ideia do que pode estar acontecendo para ele não entrar no laço? Mesmo sem o boolean found e o If ele ignora e vai direto pra mensagem de que selecionou com sucesso :?
É a primeira vez que posto por aqui, então desculpem uma primeira vez tão longa :smiley:

Não deveria ser:

[code]while(rs.next()){}

Em vez de:

while(rs.next){}

?[/code]

E outra, você atribuiu rs.next() a variável found. Por que não usa ela dentro do while?

Isso

while(rs.next){ 

Nunca irá funcionar, next não é um atributo, é um método.

Agora, se foi apenas um erro de digitação, temos o seguinte:
Suponha que você tenha apenas um resultado na consulta. Quando você chama

boolean found = rs.next(); 

Já consumiu o retorno. Ao chamar rs.next() novamente, ele não estará mais na posição 0 e sim na posição 1, que é a única que existe. Assim sendo, rs.next() retorna false, o que implica em não entrar no while.

[quote=Ruttmann]Não deveria ser:

[code]while(rs.next()){}

Em vez de:

while(rs.next){}

?[/code]

Opa! Erro de digitação…

E outra, você atribuiu rs.next() a variável found. Por que não usa ela dentro do while?

Tentei e me retornou um loop infinito… (mas pelo menos me retornou o resultado certo no console). Alguma ideia de como fazê-lo parar? Não consigo mais pensar em nada! Estou apanhando desse cidadão desde ontem a noite :cry:

[quote=drsmachado]Isso

while(rs.next){ 

Nunca irá funcionar, next não é um atributo, é um método.

Agora, se foi apenas um erro de digitação, temos o seguinte:
Suponha que você tenha apenas um resultado na consulta. Quando você chama

boolean found = rs.next(); 

Já consumiu o retorno. Ao chamar rs.next() novamente, ele não estará mais na posição 0 e sim na posição 1, que é a única que existe. Assim sendo, rs.next() retorna false, o que implica em não entrar no while.[/quote]

Consegui entender, mas não consigo achar uma solução para isso… alguma dica ou exemplo que eu possa utilizar?

A solução é retirares a linha que não serve para nada e te está a provocar essa confusão:

boolean coisa = rs.next();
//Se rs.next() é true e você faz
while(coisa){}
//cai em um loop infinito, pois não muda nunca o valor de coisa

Você precisa desta linha para que?

boolean found = rs.next();  

Independente do valor de found, se rs.next() é true, vai entrar no while. E se não for, não entra. Então por que isso?
É o mesmo que fazer:

if(rs.next()){
   while(rs.next()){}
}

Não faz sentido…
Logo, tire esta linha e seja feliz

boolean found = rs.next();  

[quote=drsmachado] boolean coisa = rs.next(); //Se rs.next() é true e você faz while(coisa){} //cai em um loop infinito, pois não muda nunca o valor de coisa
Você precisa desta linha para que?

boolean found = rs.next();  

Independente do valor de found, se rs.next() é true, vai entrar no while. E se não for, não entra. Então por que isso?
É o mesmo que fazer:

if(rs.next()){
   while(rs.next()){}
}

Não faz sentido…
Logo, tire esta linha e seja feliz

boolean found = rs.next(); [/quote]

Desespero! hahahahahhaha Por isso aquilo estava ali… removi a linha e deixei somente o while(rs.next()){}
Agora ele não consegue mais pegar o valor de nomeFantasia em nenhum momento e não me retorna nada…

Nos System.out.println antes ele me mostrava a sql com aquele valor capturado, agora só mostra a sql sem esse valor… ex: SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE ‘%’; (assim mesmo, sem nada antes do símbolo de porcentagem)

Então vamos arrumar isso.
1 - Troque esta expressão

String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE '"+nomeFantasia+"%'";

Por

String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE ?";

E faça assim:

 PreparedStatement pstmt = con.prepareStatment(sql);  
pstmt.setString(1, "%" + nomeFantasia + "%");
            System.out.println("Passei aqui  " +sql);

E veja o espetáculo acontecer…

[quote=drsmachado]Então vamos arrumar isso.
1 - Troque esta expressão

String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE '"+nomeFantasia+"%'";

Por

String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE ?";

E faça assim:

 PreparedStatement pstmt = con.prepareStatment(sql);  
pstmt.setString(1, "%" + nomeFantasia + "%");
            System.out.println("Passei aqui  " +sql);

E veja o espetáculo acontecer…[/quote]

Aquela linha que você me indicou não funcionou, do outro jeito começou a funcionar e a retornar o valor certo! Agora só falta eu conseguir jogar tudo aquilo no combo… tá complicado! Arrumo uma coisa, a outra não funciona! hahahahaha

O que está acontecendo naquele combo:

public void carregaComboEmpresas(){
        for(int i=0; i<listaEmpresas.size();i++){
            comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);
        }
}

private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){  
             this.trechoNome = (txtPesquisa.getText());  
   
             IEmpresa iEmp = new Empresa DAO();   
   
             listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO  
             this.carregaComboEmpresas(listaEmpresas); 
   
}  

O que estou fazendo de tão errado? :?

Ah! Muito obrigado a todos que estão respondendo e ajudando! Com certeza estou aprendendo muito com vocês (fora que estão salvando minha pele!!!)

Vamos com calma.
A forma que eu postei é exatamente igual a que você estava fazendo, só que do jeito certo.

Vamos primeiro fazer rodar, depois adequamos ao modo mais correto e elegante.

Eu gosto mais de usar a interface List do que diretamente sua implementação ArrayList, logo, eu mudaria isso, da seguinte forma:

//Tipo de retorno alterado para a interface java.util.List<E>
public List<Empresa> selectEmpresaTrechoNome(string nomeFantasia){  
		//Variável do tipo java.util.List<E> onde o tipo de dado é Empresa
		//A sintaxe do java 7 deixa usar ArrayList<>, mas eu não curto
        List<Empresa> listaEmpresas = new ArrayList<Empresa>();  
		
        try{  
            Connection con = conn.getConexao();  
			//O SQL precisa ser assim, o ? indica que um parâmetro será colocado ali
            String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE ?";  
            PreparedStatement pstmt = con.prepareStatment(sql);  
			//Aqui eu defino o parâmetro como sendo uma String, na posição 1 (irá 
			//substituir o primeiro ? que encontrar
			//A query final será SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE '" + nomeFantasia + "%'"
			//Igual a tua, mas, se o nome da empresa tiver um apóstrofo ('), você não terá problemas.
			pstmt.setString(1, nomeFantasia + "%");
            ResultSet rs = pstmt.executeQuery();  
		
            while(rs.next){  
                 if(found){  
                    Empresa iEmp = new Empresa();  
                    iEmp.setCodigo(rs.getInt("CODIGO"));  
                    iEmp.setRazaoSocial(rs.getString("RAZAOSOCIAL"));  
                    iEmp.setNomeFantasia(rs.getString("NOMEFANTASIA"));  
                    //aqui vem mais uns 17 campos! Estou fazendo a mão, então não vou copiar tudo  
                    listaEmpresas.add(iEmp);  
               }    
            }  
        }catch(Exception e){  
                 System.out.println("Problemas ao selecionas todas as empresas "+e.getMessage());  
        } 
		return listaEmpresa;  
}  

[quote=drsmachado]Vamos com calma.
A forma que eu postei é exatamente igual a que você estava fazendo, só que do jeito certo.

Vamos primeiro fazer rodar, depois adequamos ao modo mais correto e elegante.

Eu gosto mais de usar a interface List do que diretamente sua implementação ArrayList, logo, eu mudaria isso, da seguinte forma:

[code]
//Tipo de retorno alterado para a interface java.util.List
public List selectEmpresaTrechoNome(string nomeFantasia){
//Variável do tipo java.util.List onde o tipo de dado é Empresa
//A sintaxe do java 7 deixa usar ArrayList<>, mas eu não curto
List listaEmpresas = new ArrayList();

    try{  
        Connection con = conn.getConexao();  
		//O SQL precisa ser assim, o ? indica que um parâmetro será colocado ali
        String sql = "SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE ?";  
        PreparedStatement pstmt = con.prepareStatment(sql);  
		//Aqui eu defino o parâmetro como sendo uma String, na posição 1 (irá 
		//substituir o primeiro ? que encontrar
		//A query final será SELECT * FROM EMPRESA WHERE NOMEFANTASIA LIKE '" + nomeFantasia + "%'"
		//Igual a tua, mas, se o nome da empresa tiver um apóstrofo ('), você não terá problemas.
		pstmt.setString(1, nomeFantasia + "%");
        ResultSet rs = pstmt.executeQuery();  
	
        while(rs.next){  
             if(found){  
                Empresa iEmp = new Empresa();  
                iEmp.setCodigo(rs.getInt("CODIGO"));  
                iEmp.setRazaoSocial(rs.getString("RAZAOSOCIAL"));  
                iEmp.setNomeFantasia(rs.getString("NOMEFANTASIA"));  
                //aqui vem mais uns 17 campos! Estou fazendo a mão, então não vou copiar tudo  
                listaEmpresas.add(iEmp);  
           }    
        }  
    }catch(Exception e){  
             System.out.println("Problemas ao selecionas todas as empresas "+e.getMessage());  
    } 
	return listaEmpresa;  

}
[/code][/quote]

Fiz assim… funciona certinho! Só falta conseguir colocar no combo! :smiley:

Beleza.
Vi que você tem dois métodos distintos.

ublic void carregaComboEmpresas(){  
        for(int i=0; i<listaEmpresas.size();i++){  
            comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);  
        }  
}  
  
private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){    
             this.trechoNome = (txtPesquisa.getText());    
     
             IEmpresa iEmp = new Empresa DAO();     
     
             listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO    
             this.carregaComboEmpresas(listaEmpresas);   
     
}  

Se não ocorre nenhum erro, me parece que está certo, salvo pelo parâmetro do método preencheCombo

[code]
ublic void carregaComboEmpresas(List listaEmpresas){
for(int i=0; i<listaEmpresas.size();i++){
comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);
}
}

private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){
this.trechoNome = (txtPesquisa.getText());

         IEmpresa iEmp = new Empresa DAO();     
 
         listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO    
         this.carregaComboEmpresas(listaEmpresas);   

} [/code]

[quote=drsmachado]Beleza.
Vi que você tem dois métodos distintos.

ublic void carregaComboEmpresas(){  
        for(int i=0; i<listaEmpresas.size();i++){  
            comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);  
        }  
}  
  
private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){    
             this.trechoNome = (txtPesquisa.getText());    
     
             IEmpresa iEmp = new Empresa DAO();     
     
             listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO    
             this.carregaComboEmpresas(listaEmpresas);   
     
}  

Se não ocorre nenhum erro, me parece que está certo, salvo pelo parâmetro do método preencheCombo

[code]
ublic void carregaComboEmpresas(List listaEmpresas){
for(int i=0; i<listaEmpresas.size();i++){
comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);
}
}

private void txtPesquisaKeyReleased(java.awt.evetent.KeyEvent evt){
this.trechoNome = (txtPesquisa.getText());

         IEmpresa iEmp = new Empresa DAO();     
 
         listaEmpresas = iEmp.selectEmpresasTrechoNome(trechoNome.toUpperCase());//aquele carinha da DAO    
         this.carregaComboEmpresas(listaEmpresas);   

} [/code][/quote]

Fiz isso, mudei o parâmetro do método carregaComboEmpresas e ele ainda não funciona… não dá erro, apenas não lista as empresas selecionadas… :?

Então existe algo errado aí.
Infelizmente não posso criar nada parecido aqui, pois trabalho só com web e fica chato mexer com desktop.
Já debugou para ver se o método carregaComboEmpresas está sendo executado?

[quote=drsmachado]Então existe algo errado aí.
Infelizmente não posso criar nada parecido aqui, pois trabalho só com web e fica chato mexer com desktop.
Já debugou para ver se o método carregaComboEmpresas está sendo executado?[/quote]

Depois da mudança proposta por você, não… vou debugar aqui! Acho que consigo me virar agora, já que o pior erro já está resolvido. Mas, se eu não conseguir, volto e mostro o que está acontecendo…

Cara, muito obrigado pela sua disposição e paciência em me ajudar!
Sério, eu já estava começando a desistir de tudo!
Abraço :smiley:

Relaxa camarada, dificuldades existem para a gente superar, é isso que nos torna melhores.
Estamos no mesmo barco, temos o mesmo objetivo. Um dia eu também estive no teu lugar, passei dificuldades semelhantes e insisti.
Não sei de tudo, longe disso, mas já estou confortável com muita coisa.

É… não consegui resolver o problema do combo que não carrega!

Quando vou percorrer a lista no método carregaComboEmpresas, ele me fala “a variável i não existe no contexto”!

Para quem quiser entender melhor, o código para selecionar a empresa e para carregar o combo são esses

public void carregaComboEmpresas(List<Empresa> listaEmpresas){
    for(int i=0; i<listaEmpresas.size();i++){
           comboEmpresa.addItem(listaEmpresas.get(i).getNomeFantasia);
     }
}

private void txtPesquisaKeyReleased(java.awt.event.KeyEvent evt){
        this.trechoNome = (txtPesquisa.getText());

        IEmpresa iEmp = new EmpresaDAO();
        listaEmpresas = iEmp.selectEmpresaTrechoNome(trechoNome.toUpperCase());
 
        this.carregaComboEmpresas(listaEmpresas);
}

Então ele dispara erro.
Preciso do stackTrace para tentar uma análise mais adequada. Pelo código, está ok. Agora, como a mensagem é esta, é muito estranho.

[quote=drsmachado]Então ele dispara erro.
Preciso do stackTrace para tentar uma análise mais adequada. Pelo código, está ok. Agora, como a mensagem é esta, é muito estranho.[/quote]

Desculpa a demora em responder… eu estava com minha prof. orientadora mostrando o resto do sistema… tudo ok, só este problema mesmo :?

Como faço pra pegar o stackTrace?

Eu vou apelar e resolver de uma maneira menos bonita… inserir uma JTable e listar todas as empresas cadastradas (por sorte serão poucas), dai o usuário clica, ela preenche os campos e estará todo mundo habilitado a alterar ou excluir a empresa. É a solução mais rápida, pois vou apresentar o tcc amanhã :?