Problemas para inserir valores em chave estrangeira utilizando SWING.. [RESOLVIDO]

30 respostas
A
Boa noite galera!!! To tentando aprender aqui como inserir uma chave estrangeira numa tabela no banco de dados, mas até agora a lógica eu sei, to com dificuldades é na implementação desta lógico... é o seguinte, no banco de dados tenho duas tabelas simples, cliente e compra, onde um cliente pode fazer várias compras, nesse relacionamento a chave primária da tabela cliente vai para a tabela compras, agora eu quero aprender como inserir dentro da tabela compras o valor da chave primária da tabela cliente durante uma venda, terei um ComboBox listando os nomes dos clientes, e usuário vai descrever a venda e escolher o cliente que irá comprar no ComboBox, tenho a interface feita, estou desenvolvendo utilizando DAO por camadas, mas a maior dificuldade é na parte que vai para o Banco, ou seja a parte de Persistencia, vo postar os códigos que tenho aqui, mas nao ta dando certo, ta dando erro, e pelo jeito é erro na codificação..nos códigos estão a lógica que criei, e também vo postar o erro que está aparecendo.... ERRO DO MÉTODO DAO
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:343)
        at Banco.TesteDAO.inserirCompra(TesteDAO.java:47)
        at Negocio.CompraNegocio.inserirCompra(CompraNegocio.java:21)
        at Apresentacao.Frame.bt_produtoActionPerformed(Frame.java:144)
        at Apre
MÉTODO QUE INSERE COMPRAS DO DAO
public void inserirCompra(Compra compra ,String nomecliente) throws SQLException{

		// Abrir uma conexao
		Connection conn = Conexao.getConexao();

                String val = "Select idcliente cliente where nome = nomecliente";
		PreparedStatement stmt = conn.prepareStatement(val);
                ResultSet rs = stmt.executeQuery();
                while(rs.next()){

                       compra.setIdcliente(rs.getInt("idcliente"));
                }




		String sql = "insert into compra(produto,idcliente)" + "values(?,val)";
                PreparedStatement stmt2 = conn.prepareStatement(sql);
                stmt2.setString(1, compra.getProduto());
                stmt2.setInt(2,compra.getIdcliente());
                stmt2.execute();
                stmt2.close();

	}
MÉTODO DA REGRA DE NEGÓCIO
public void inserirCompra(String produto,String nomecliente) throws SQLException{
        Compra compra = new Compra(produto);
        TesteDAO cDAO = new TesteDAO();
        cDAO.inserirCompra(compra, nomecliente);
        
    }
BOTAO CADASTRAR PRODUTOS
private void bt_produtoActionPerformed(java.awt.event.ActionEvent evt) {


              if(evt.getSource() == bt_produto){
                  CompraNegocio compra = new CompraNegocio();
            try {
                compra.inserirCompra(tf_produto.getText(), (String) cbox.getSelectedItem().toString());
            } catch (SQLException ex) {
                Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
            }
              }
    }

30 Respostas

A

E ai galera, alguma solução???

V

Faltou a primeira linha do erro, que diz o nome da exception.

A

E ai Viny blz cara???
Vo postar ai pra você da uma Analisada!!!
Obrigado!!!

12/04/2010 15:13:13 Apresentacao.Frame bt_produtoActionPerformed SEVERE: null org.postgresql.util.PSQLException: ERROR: syntax error at or near "cliente" at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254) at Banco.TesteDAO.inserirCompra(TesteDAO.java:47) at Negocio.CompraNegocio.inserirCompra(CompraNegocio.java:21) at Apresentacao.Frame.bt_produtoActionPerformed(Frame.java:144) at Apresentacao.Frame.access$100(Frame.java:28) at Apresentacao.Frame$2.actionPerformed(Frame.java:72)

V

Faltou o FROM no seu SQL.

A

opa… vo testar aqui… :smiley:

A
Ai viny, fiz uma modificações no inserir do DAo aqui, mas deu o seguinte erro
12/04/2010 15:31:33 Apresentacao.Frame bt_produtoActionPerformed
SEVERE: null
org.postgresql.util.PSQLException: ERROR: insert or update on table "compra" violates foreign key constraint "cliente_compra_fk"
  Detalhe: Key (idcliente)=(0) is not present in table "cliente".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:343)
        at Banco.TesteDAO.inserirCompra(TesteDAO.java:61)
        at Negocio.CompraNegocio.inserirCompra(CompraNegocio.java:21)
        at Apresentacao.Frame.bt_produtoActionPerformed(Frame.java:144)
        at Apresentacao.Frame.access$100(Frame.java:28)
        at Apresentacao.Frame$2.actionPerformed(Frame.java:72)
o código inserir do DAO fico assim
public void inserirCompra(Compra compra ,String nomecliente) throws SQLException{

		// Abrir uma conexao
		Connection conn = Conexao.getConexao();

                String val = "Select idcliente from cliente where nome = ?";
		PreparedStatement stmt = conn.prepareStatement(val);
                stmt.setString(1, compra.getNomecliente());
                ResultSet rs = stmt.executeQuery();
                while(rs.next()){

                       compra.setIdcliente(rs.getInt("idcliente"));
                }




		String sql = "insert into compra(produto,idcliente)" + "values(?,?)";
                PreparedStatement stmt2 = conn.prepareStatement(sql);
                stmt2.setString(1, compra.getProduto());
                stmt2.setInt(2,compra.getIdcliente());
                stmt2.execute();
                stmt2.close();

	}
A

outro detalhes, meu comboBox nao está listando corretamente os dados do Banco…
quer ki poste os códigos referentes a listagem do Combobox??? talvez pode ser isso!!

V

Use um depurador e veja, a partir da linha 19, se os valores passados no set estão certos. Por exemplo, getProduto() retorna mesmo o id do produto? E é mesmo uma String?

O seu erro é bem claro, ele está falando que a foreign key está sendo violada. Então, ou a compra que vc está tentando cadastrar não existe na tabela compra, ou o produto não existe na tabela de Produtos.

A
Viny, estou modificando o metodo de inserir do Dao aqui, ele ta com alguns erros, vo testar-lo e se der erro posto o novo codigo DAO e erro Blz????? essa é minha classe compra, deu uma ohada, e pelo jeito nao tem nada de errado!!
package Negocio;

/**
 *
 * @author Anderson
 */
public class Compra {

    private int idcompra;
     private String produto;
     private String nomecliente;
     private int idcliente;

    public int getIdcliente() {
        return idcliente;
    }

    public void setIdcliente(int idcliente) {
        this.idcliente = idcliente;
    }
     

      public Compra(String produto){
         this.produto = produto;
     }

    public int getIdcompra() {
        return idcompra;
    }

    public void setIdcompra(int idcompra) {
        this.idcompra = idcompra;
    }

    public String getNomecliente() {
        return nomecliente;
    }

    public void setNomecliente(String nomecliente) {
        this.nomecliente = nomecliente;
    }

    public String getProduto() {
        return produto;
    }

    public void setProduto(String produto) {
        this.produto = produto;
    }
    
     

    

  
}
A
ai, esse é meu novo método do DAO, mas ta dando o mesmo erro :(
public void inserirCompra(Compra compra ,String nomecliente) throws SQLException{

		// Abrir uma conexao
		Connection conn = Conexao.getConexao();
                Cliente cliente = new Cliente(nomecliente);

                String val = "Select idcliente from cliente where nome = ?";
		PreparedStatement stmt = conn.prepareStatement(val);
                stmt.setString(1, cliente.getNome());
                ResultSet rs = stmt.executeQuery();
                while(rs.next()){

                       cliente.setIdcliente(rs.getInt("idcliente"));
                       compra.setIdcliente(cliente.getIdcliente());
                }




		String sql = "insert into compra(produto,idcliente)" + "values(?,?)";
                PreparedStatement stmt2 = conn.prepareStatement(sql);
                stmt2.setString(1, compra.getProduto());
                stmt2.setInt(2,compra.getIdcliente());
                stmt2.execute();
                stmt2.close();

	}
A

Isso que to fazendo é só um teste pra aprender a inserir valores em chaves estrangeiras…no meu bando de dados eu só tenho 2 tabelas… cliente e compra
vo postar elas aqui…
TABELA CLIENTE

CREATE TABLE cliente ( idcliente serial NOT NULL, nome character varying(10) NOT NULL, CONSTRAINT cliente_pk PRIMARY KEY (idcliente) )
TABELA COMPRA

CREATE TABLE compra ( idcompra serial NOT NULL, produto character varying(10) NOT NULL, idcliente integer NOT NULL, CONSTRAINT compra_pk PRIMARY KEY (idcompra), CONSTRAINT cliente_compra_fk FOREIGN KEY (idcliente) REFERENCES cliente (idcliente) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION )

A

Tem um problema tbm, meu ComboBoz nao está preenchendo corretamente os dados do banco de daods,será que nao é isso??eu tentei aqui, mas nao conseguir faze-lo preencher corretamente…como faz?? tavez o problema é esse!!!
MÉTODO QUE PREENCHER COMBOBOX

private void preencherComboBox() throws SQLException{ CompraNegocio compra = new CompraNegocio(); List<Cliente> lista = compra.listar(); cbox.removeAllItems(); cbox.addItem(lista); }

I

a combo box nao vai inserir a lista inteira de uma vez…voce tem que jogar ela em um for() …faz um for normal com um contador para iterar cada item da lista, em cada “loop” voce da um .addItem(lista)

A

Fiz isso mas mesmo assim os dados estão aparecendo como simbolos…

I

A combo deve estar pegando o endereço de referência…creio que voce tera de implementar o método toString() na sua classe compra…aonde estao os getters e setters …dai axo que resolve

A

e ai viny, alguma solução??

A

:frowning:

M

você debugou a classe ? resolveu?

caso seja não e não, debuga e olha o que que você está inserindo nos sets que você chama no preparedStatement, ou antes da linha 20 que está pegando o sql, da system.out exibindo os parâmetros que você seta no preparedStatement, para olhar o que que você está inserindo…

quanto a parte da combo, monte um loop ali percorrendo a lista que é recebida do seu dao e dando um add na sua combo (acho que é isso, faz tempo que não mecho com swing) para cada item da lista.

A

Deixa eu pergunta uma coisa pra voces…minha logica para insercao em chave estrangeira esta certo???
talvez esteja errado!!

I

Amigo eu não sou nenhum guru do java, mas vou tentar te ajudar com o que eu ja sei…
Sobre seu método DAO de insert: pelo o que eu entendi voce esta passando uma string que contem um “select idcliente from cliente…” para o prepareStatement ler, eu nao imagino como isso possa funcionar, pra mim em hora nenhuma voce recuperou o valor do idcliente, voce apenas o encontrou e o carregou no objeto “compra”…porém não passou o id dele para o segundo select. Creio que por isso ele da o erro de violação…é minha opnião, mas como eu disse…eu estou aprendendo ainda…um exemplo tosco de como recuperar esse valor seria : “int x = compra.getIdCliente()

E quanto a sua combobox, voce está trazendo qual valor do banco?, eu tive um problema uma vez semelhante, no qual eu solucionei implementando o toString() no meu Bean que estava sendo usado para trazer os valores…como eu trazia do objeto Bean uma variavel do tipo string, os valores listados na combo eram os valores de referencia do objeto…mas bom, pelo jeito não funcionou pra vc.
Espero ter ajudado em algo!
Abs!

A
como seria na sua lógica o meu método DAO de inserir compras capturando a chave primária para inserir na chave estrangeira???????? ??????? Vo postar o meu método de listar, que busca os dados para listar no ComboBox...... eu ja fiz o loop que vcs falaram, mas os dados estão vindo em forma de simbolo no ComboBox... mas minha maior preocupação é na inserção de valores na chave estrangeira... eu queria muito mesmo uma solução... por que preciso disso para implementar no TCC da Facul :cry:
public List<Cliente> listar() throws SQLException{

        Connection conn = Conexao.getConexao();

		String sql = "Select * from cliente order by nome";
		PreparedStatement stmt = conn.prepareStatement(sql);

		// Esse método é utilizado para apontar para os dados do BD
		ResultSet rs = stmt.executeQuery();

		//Cria uma lsita para armazenar os valores que serão buscados
		 List<Cliente> minhaLista = new ArrayList<Cliente>();

		while(rs.next()){
			// Essa Rotína pega os dados do banco e armazena nesse objeto do tipo contato
			Cliente cliente = new Cliente(rs.getString("nome"));
                        cliente.setIdcliente(rs.getInt("idcliente"));
                        

			//Essa rotína adiciona os dados de contato no objeto minhaLista
			minhaLista.add(cliente);

		 }
		 rs.close();
		 stmt.close();
		 return minhaLista;
      }
A

To triste galerinha do forum por nao está conseguindo, na faculdade não tem nenhum professor que saiba java pra me ajudar :cry:

I

Eu faria o DAO assim:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import teste.bean.CompraBean;
import teste.jdbc.FabricaConexao;

public class CompraDAO {

	public void inserirCompra(CompraBean bean , String nome){
		int idresult=0;
		Connection con = FabricaConexao.getConexao();
		String sql = "Select * from cliente where nome ='"+nome+"'";
		try{
			PreparedStatement ps = con.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			if(rs.next()==true){
				bean.setIdcliente(rs.getInt("idcliente"));	
				idresult = bean.getIdcliente();
			}else{
				System.out.println("Cliente não encontrado");
			}
			rs.close();
			ps.close();
		}catch(SQLException e){
			System.out.println("Erro de SQL");
			e.printStackTrace();
		}
		
		String sql2 = "insert into compra(idcliente,produto) values("+idresult+",?)";
		   try {
			PreparedStatement ps2 = con.prepareStatement(sql2);
			ps2.setString(1, bean.getProduto());
			ps2.execute();
			ps2.close();
		} catch (SQLException e) {
			System.out.println("Erro no SQL2");
			e.printStackTrace();
		}
	}
	
}

Não sei se é o jeito mais correto, mas eu testei aqui e funcionou! =)
Eu fiz rapidao aqui e nao me atentei…mas a sua classe Conexao eu chamo de FabricaConexao, e a sua classe Compra que contem os get() e set() eu chamo de CompraBean …o resto acho que voce vai entender…
Abs!

A

Sua lógica ta igual a minha!!! :-o
Eu fiz um teste aqui que foi o seguinte, cancelei o ComboBox e coloquei um TextFild, dentro do TextFild eu escrevia o nome da pessoa que iría comprar, e deu certo, o ID referente a pessoa foi inserido perfeitamente dentro da tabela Compras,sendo assim ,o problema é no ComboBox, que esta listando os nomes do Banco de Dados em forma de Simbolo…por que com o textfild, digitando o nome referente aos existentes no banco de dados, ele insere perfeitamente na tabela compras o ID referente ao nome do cliente na chave estrangeira…Agora tenho que resolver o problema do ComboBox, para ele listar os nomes perfeitamentes dentro dele…

I

Eu não disse que a lógica estava errada, só o jeito de recuperar o id do cliente e o jeito de passar ele no segundo select dentro do prepareStatement. No código que voce postou anteriormente, a sua variavel “val” era passada…mas bom…se está inserindo corretamente, vamos ao combobox…os simbolos que estão sendo mostrados, é algo nessa formatação: 13213@jdsjisidsaidji ? , manda um print ou o proprio simbolo que ta aparecendo ai…eu vou fazendo uma combo aqui para testar seu metodo listar

I

Um exemplo da combobox …eu testei aqui e funcionou! :stuck_out_tongue:

private JComboBox getJComboBox1() {
		if (jComboBox1 == null) {
		    jComboBox1 = new JComboBox();
		    jComboBox1.setBounds(new Rectangle(9, 58, 214, 25));
			
		    ClienteDAO dao = new ClienteDAO();
		    List<ClienteBean> lista2 = new ArrayList<ClienteBean>();
			try {
				lista2 = dao.listar();
				for (ClienteBean clienteBean : lista2) {
						jComboBox1.addItem(clienteBean.getNome());
					                                              } 
			} catch (SQLException e) {
                                System.out.println("ERRO NA LISTAGEM");
				e.printStackTrace();
			}
	}
		
		return jComboBox1;
	}

Com esse metodo que retorna uma combo, é só voce dar um add() no seu JPanel que funciona, ex: jMeuPainel.add(getJComboBox1());
Testa ai e ve se funciona!
Abs!

A

Ai mano, eu tava analisando seu codigo de ComboBox e vi o que tinha de errado no meu…
quando eu estava chamando a função do combo box estava assim --> cbox.additem(Cli)
mas pelo que eu vi no seu código eu tinha esquecido de chamar o método getNome()… e o certo era --> cbox.additem(Cli.getNome())
Obrigado por ter postado seu Método de ComboBox ail me ajudou a achar o meu erro!!! Vlw de coração´…

I

Aee! Maravilha! põe o [Resolvido] no topico entao, vai que mais alguem tenha o mesmo problema! Pra isso que serve a comunidade! =)
Abs!

F

Amigo se vc ta com problemas
vc pode inserir diretamento do Form
Te mandarei um exemplo pra que de uma olhada
Certo.Até mais qualquer duvida so mandar.

public void cadastrar() {
        try {
            String sqlinsert = "INSERT INTO funcionario (nome, endereco, comissao,hora_expediente,id_funcao,cpf)values('" + jTNome.getText() + "','" + jTEndereco.getText() + "','" +
                    jTComissao.getText() + "','" + jTHora_expediente.getText() + "','" + jTFuncao.getText() + "','" + jFCpf.getText() + "')";
            funcao.statement.executeUpdate(sqlinsert);
            JOptionPane.showMessageDialog(null, " Funcionário inserido com Sucesso");
        } catch (SQLException erro) {
            JOptionPane.showMessageDialog(null, "Erro ao tentar Salvar o Funcionário " + erro);
        }
    }

Espero ter ajudado.

V

fgs4ntos:
Amigo se vc ta com problemas
vc pode inserir diretamento do Form
Te mandarei um exemplo pra que de uma olhada
Certo.Até mais qualquer duvida so mandar.

public void cadastrar() {
        try {
            String sqlinsert = "INSERT INTO funcionario (nome, endereco, comissao,hora_expediente,id_funcao,cpf)values('" + jTNome.getText() + "','" + jTEndereco.getText() + "','" +
                    jTComissao.getText() + "','" + jTHora_expediente.getText() + "','" + jTFuncao.getText() + "','" + jFCpf.getText() + "')";
            funcao.statement.executeUpdate(sqlinsert);
            JOptionPane.showMessageDialog(null, " Funcionário inserido com Sucesso");
        } catch (SQLException erro) {
            JOptionPane.showMessageDialog(null, "Erro ao tentar Salvar o Funcionário " + erro);
        }
    }

Espero ter ajudado.

Você ressuscita um tópico após mais de 5 meses do autor ter resolvido, e ainda aconselha o autor a usar Statement no lugar de PreparedStatement?

Tomara que ninguém chamado “Irv’s” use o seu banco, muito menos se o endereço dele for ao lado do “John Pub’s”. Seu SQL vai falhar de cara se isso ocorrer. Dá uma lida sobre preparedstatement, livre-se daquelas concatenações, evite esse erro e, de quebra, deixe seu sistema seguro contra SQL Injection. :wink:

Criado 11 de abril de 2010
Ultima resposta 9 de ago. de 2010
Respostas 30
Participantes 5