Como não deixar salvar 2 estados com siglas iguais

12 respostas
R

Estou tendo que fazer o meu 1º projeto na faculdade e o professor pediu para fazermos o método cadastrar, consultar, salvar.

Porem quero adicionar um campo para não deixar salvar 2 Siglas iguais.

Segue meu código no salvar

public void adiciona (EstadoDTO estado){
    String sql = "INSERT INTO estado (sigla) VALUES(?)";
    try {
        PreparedStatement stmt = conn.prepareStatement(sql);
        stmt.setString (1,estado.getSigla());
        stmt.execute();
        stmt.close();
        
    
    }
    catch (SQLException e) {
        throw new RuntimeException(e);
    }

}

Consigo inserir bonitinho na View, excluo, consulto, mas não sei fazer essa validação, alguem me ajuda?

12 Respostas

V

Na criação da tabela do banco, você deve inserir uma constraint UNIQUE.

Posta o SQL que você usou para criar essa tabela e o tipo de banco de dados que você está usando.

R

bom dia.

Segue como minha tabela estado, estava no banco

CREATE TABLE estado ( id_estado serial NOT NULL, sigla character varying(2) NOT NULL, CONSTRAINT chave_primaria_estado PRIMARY KEY (id_estado) )

Já mudei o sigla character varying(2) NOT NULL UNIQUE,

O sistema não esta deixando cadastrar com nomes iguais, agora preciso que o sistema exiba uma msg onde alerta que não pode por ter já cadastrado, como posso fazer?

V

Captura a exception no try catch e põe a mensagem de erro.

R

Não entendi o que você pediu para eu fazer, mas me retorna esse erro

[color=red] Exception in thread “AWT-EventQueue-0” java.lang.RuntimeException: org.postgresql.util.PSQLException: ERRO: duplicar valor da chave viola a restrição de unicidade “estado_sigla_key”
Detalhe: Chave (sigla)=(SP) já existe.
[/color]

V

Aquele “catch” ali serve para você tratar erros:

public void adiciona (EstadoDTO estado){ String sql = "INSERT INTO estado (sigla) VALUES(?)"; try { PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString (1,estado.getSigla()); stmt.execute(); stmt.close(); } catch (SQLException e) { if (e.getMessage().contains("estado_sigla_key")) { JOptionpane.showMessageDialog(this, "Estado duplicado!"); } else { throw new RuntimeException(e); } } }

R

ihh informei coisa errada o método que eu citei anteriormente é na minha DAO.

Esta show da forma que você me explicou, porem esse JOptionpane, não deveria ser dentro do método salvar na view?

Segue o código e como faço para fazer isso?

private void btSalvarActionPerformed(java.awt.event.ActionEvent evt) {                                         
        EstadoDTO estado = new EstadoDTO();
        // estado.setSigla (txtSigla.getText());

        if (novoEdit == true){
            if ((txtSigla.getText().equals(""))){
                JOptionPane.showMessageDialog(rootPane, "Nome em Branco");
            }

            else{
                estado.setSigla(txtSigla.getText());
                EstadoDAO dao = new EstadoDAO();
                dao.adiciona(estado);
                JOptionPane.showMessageDialog(rootPane, "Cadastro Efetuado");
            }
            txtSigla.setText("");
            txtSigla.setEnabled(false);

        }
        else if (novoEdit == false) {
            estado.setId_estado(Integer.valueOf(tbEstado.getModel().getValueAt(tbEstado.getSelectedRow(),0).toString()));
            estado.setSigla(txtSigla.getText());
            EstadoDAO dao = new EstadoDAO();
            dao.Editar(estado);
            JOptionPane.showMessageDialog(rootPane, "Cadastro Atualizado");
        }
        txtSigla.setText("");
        txtSigla.setEnabled(false);
        preencherTabela("");

        btNovo.setEnabled(true);
        btSalvar.setEnabled(false);
        btDeletar.setEnabled(false);
        btEditar.setEnabled(false);
    }

Pois coloquei o código que você passou agora e na DAO fica apresentando para eu criar a classe
“JOptionpane” no pacote Estado.

V

Nesse caso sua DAO poderia:
a) Retornar um código de erro (false se não cadastrou, ou um número ou enum indicando o tipo de erro);
b) Disparar uma exceção criada por você, como uma EstadoDuplicadoException. Aí vc captura a exceção na VIEW e mostra a mensagem de erro.

R

ixe já não consigo acompanhar seu raciocínio mais não.

Consegue fazer um exemplo para eu me basear?

V
  1. Criar a classe da Exception:

public class EstadoDuplicadoException extends Exception { public void EstadoDuplicadoException() { super("Estado duplicado!"); } }

  1. Dispara-la no DAO:

public void adiciona (EstadoDTO estado) throws EstadoDuplicadoException { String sql = "INSERT INTO estado (sigla) VALUES(?)"; try { PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString (1,estado.getSigla()); stmt.execute(); stmt.close(); } catch (SQLException e) { if (e.getMessage().contains("estado_sigla_key")) { throw new EstadoDuplicadoException(); } else { throw new RuntimeException(e); } } }

V
  1. Usar isso na view:

try { estado.setSigla(txtSigla.getText()); EstadoDAO dao = new EstadoDAO(); dao.adiciona(estado); JOptionPane.showMessageDialog(rootPane, "Cadastro Efetuado"); } catch (EstadoDuplicadoException e) { txtSigla.requestFocusInWindow(); JOptionPane.showMessageDialog(this, "Estado duplicado!"); }

R

opa deu certo aqui, vou tentar fazer alguns ajustes que esta aparecendo a msg “Estado duplicado” ai clico em Ok vem a msg “Cadastro Efetuado” mas vou vendo aqui vlw mesmo brow.

Vou tentar nas outras tabelas dessa mesma forma que voce me ensinou.

C

Neste caso, com java e jdbc a melhor forma:

Na coluna do banco de dados, defina a sigla como unique.
No sistema, no mento de salvar… vai disparar um exceptions.
trate com try/catch, e com uma exception específica para a coluna “unique”, não com contains.
ai então, você poderá configurar uma mensagem e uma ação bem específica quando isto acontece.

Atenciosamente, Clarel

Criado 1 de setembro de 2014
Ultima resposta 2 de set. de 2014
Respostas 12
Participantes 3