Delete não funcionando no código Java

Estou fazendo uma tela dentro do VSCode para mostrar uma tabela e dentro dela há valores do meu banco de dados. A opção de remover um dado da tabela não funciona.


Verifiquei as condições, estão certas; verifiquei o código em SQL e também tá certo. Acho que o erro pode estar na PreparedStatement.

Será que o auto-commit não está desabilitado e faltou vc invocar o commit() depois do execute()?

o auto-commit tá definido como true, não deu certo :confused:

E não aparece erro nenhum no terminal?

Pode nos mostrar a classe ConnectionFactory?

Não aparece erro no terminal.
image
O comando de Insert funciona normalmente, então acho que o problema não está na conexão.

O registro não é excluído do banco de dados ou ele não é removido do seu table model?

Olhando o código, parece estar correto, porém, aparentemente você não remove a linha do registro excluído do seu table model, não seria esse o caso?

1 curtida

Ele não é excluído do bd e nem removido do table model. O teste que eu fiz usando id = 3 em vez do id = ?, excluiu do bd e removeu do table model o dado com id 3. Porém usando o “?” não acontece nenhum dos dois.

Ah, então vai naquela linha na qual vc chama o c.getId() e coloca um println para ver se esse getId() está retornando o id certo.

caramba, tá retornando 0. O atributo id tá como auto_increment no bd, então nem to colocando valor pra ele no construtor. Acho que ele não tá recebendo o valor do bd, como posso resolver isso?

Eu tenho uma ideia, mas deixa eu ver sua classe Categoria e o método de inserção antes?

Claro, segue o código:
public class Categoria {
private int id;
private String nome;

public Categoria(String nome) {
    this.nome = nome;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

}

Método de inserção:
public void insert(Categoria c) {
String sql = “insert into tbCategoria (Nome) values (?)”;

    try {
        Connection con = new ConnectionFactory().getConnection();
        PreparedStatement st = con.prepareStatement(sql);
        st.setString(1, c.getNome());
        st.execute();
        st.close();
        con.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Beleza, então vc vai ter que fazer algumas modificações no método insert.

Primeiro vc precisa trocar isto:

PreparedStatement st = con.prepareStatement(sql);

Por isto:

PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

Segundo: Logo após a linha st.execute();, adicione este trecho:

try (ResultSet result = stmt.getGeneratedKeys()) {
  if (result.next()) {
    c.setId(result.getInt(1));
  }
}

Abaixo está o código completo que usei para fazer os testes aqui. No caso eu usei o H2 para facilitar, mas no MySQL é a mesma coisa.

No meu código usei o try-with-resources, pois ele garante o fechamento dos recursos sem que precisemos invocar o close() explicitamente.

Código que usei para testar
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {
  private static final String sql = "INSERT INTO tbCategoria (Nome) VALUES (?)";

  private static void insert(Categoria c) {
    try (
      Connection conn = DriverManager.getConnection("jdbc:h2:mem:db;INIT=RUNSCRIPT FROM 'classpath:db.sql';MODE=MYSQL");

      PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
    ) {
      stmt.setString(1, c.getNome());

      if (stmt.executeUpdate() > 0) {
        try (ResultSet result = stmt.getGeneratedKeys()) {
          if (result.next()) {
            c.setId(result.getInt(1));
          }
        }
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  public static void main(String... args) {
    Categoria c = new Categoria("Eletrônicos");

    insert(c);

    System.out.println(c);
  }
}

class Categoria {
  private int id;
  private String nome;

  Categoria(String nome) {
    this.nome = nome;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getNome() {
    return nome;
  }

  public void setNome(String name) {
    this.nome = name;
  }

  @Override
  public String toString() {
    return "{id=%d, name=%s}".formatted(this.id, this.nome);
  }
}

Deu erro no RETURN_GENERATED_KEYS:
“RETURN_GENERATED_KEYS cannot be resolved or is not a field”

Vê se vc importou o Statement correto. O certo é:

import java.sql.Statement;

É importante checar porque tem uma classe com este mesmo nome, mas o pacote é diferente, é o java.beans.Statement. O correto é java.sql.Statement.

É, tinha importado um pacote diferente. Troquei o import mas mesmo assim não funcionou, o getId() continua retornando 0.

Me mostra como tá o método insert agora.

public void insert(Categoria c) {
String sql = “insert into tbCategoria (Nome) values (?)”;

    try (
            Connection con = new ConnectionFactory().getConnection();
            PreparedStatement st = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);) {
        st.setString(1, c.getNome());
        st.execute();
        try (ResultSet result = st.getGeneratedKeys()) {
            if (result.next()) {
                c.setId(result.getInt(1));
            }
        }
        st.close();
        con.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Coloca um print ou um breakpoint pra ver se ele tá caindo do if (result.next()).

E me mostra a parte que chama o método insert.

Ele não tá entrando no if.
O código que puxa o insert é de um botão na tela:
public void btCadastrarClick(ActionEvent e) {
String nome = JOptionPane.showInputDialog(this, “Insira o nome”, null);
Categoria c = new Categoria(nome);
CategoriaDAO cd = new CategoriaDAO();
cd.insert(c);
this.setVisible(false);
this.setVisible(true);
}

Em teoria, se vc colocasse um print logo abaixo de cd.insert(c), vc veria o id atualizado.

Mas se nem tá entrando naquele if, então deve ser outro problema.

Vc pode mostrar o seu CREATE TABLE?

1 curtida