Erro ao inserir dados Java Desktop

Estou recebendo essa mensagem de erro, aparentemente tem hora que funiona ao inserir uma venda

/***** TABELA CLIENTES /
CREATE TABLE tb_clientes (
id int auto_increment primary key,
nome varchar(100),
rg varchar (30),
cpf varchar (20),
email varchar(200),
telefone varchar(30),
celular varchar(30),
cep varchar(100),
endereco varchar (255),
numero int,
complemento varchar (200),
bairro varchar (100),
cidade varchar (100),
estado varchar (2)
);
/
************/

/***** TABELA FORNECEDORES /
CREATE TABLE tb_fornecedores (
id int auto_increment primary key,
nome varchar(100),
cnpj varchar (100),
email varchar(200),
telefone varchar(30),
celular varchar(30),
cep varchar(100),
endereco varchar (255),
numero int,
complemento varchar (200),
bairro varchar (100),
cidade varchar (100),
estado varchar (2)
);
/
************/

/***** TABELA FUNCIONARIOS /
CREATE TABLE tb_funcionarios (
id int auto_increment primary key,
nome varchar(100),
rg varchar (30),
cpf varchar (20),
email varchar(200),
senha varchar(10),
cargo varchar(100),
nivel_acesso varchar(50),
telefone varchar(30),
celular varchar(30),
cep varchar(100),
endereco varchar (255),
numero int,
complemento varchar (200),
bairro varchar (100),
cidade varchar (100),
estado varchar (2)
);
/
************/

/***** TABELA PRODUTOS *****/
CREATE TABLE tb_produtos (
id int auto_increment primary key,
descricao varchar(100),
preco decimal (10,2),
qtd_estoque int,
for_id int,

FOREIGN KEY (for_id) REFERENCES tb_fornecedores(id)
);
/*****************/

/***** TABELA VENDAS *****/
CREATE TABLE tb_vendas (
id int auto_increment primary key,
cliente_id int,
data_venda datetime,
total_venda decimal (10,2),
observacoes text,

FOREIGN KEY (cliente_id) REFERENCES tb_clientes(id)
);
/*****************/

/***** TABELA ITENS_VENDAS *****/
CREATE TABLE tb_itensvendas (
id int auto_increment primary key,
venda_id int,
produto_id int,
qtd int,
subtotal decimal (10,2),

FOREIGN KEY (venda_id) REFERENCES tb_vendas(id),
FOREIGN KEY (produto_id) REFERENCES tb_produtos(id)
);
/*****************/

select * from tb_clientes where nome like ‘a%’;

Coloque o seu SQL de Insert aqui para que possamos lhe ajudar?

Boa tarde meu amigo, obrigado pelo retorno

Esse e o metodo responsavel para cadastrar na classe vendaDAO

public void cadastrarVenda(Vendas obj) {
    try {

        String sql = "insert into tb_vendas (cliente_id, data_venda,total_venda,observacoes) values (?,?,?,?)";
        PreparedStatement stmt = con.prepareStatement(sql);

        stmt.setInt(1, obj.getCliente().getId());
        stmt.setString(2, obj.getDataVenda());
        stmt.setDouble(3, obj.getTotalVenda());
        stmt.setString(4, obj.getObservacoes());

        stmt.execute();
        stmt.close();
        


    } catch (Exception erro) {

        JOptionPane.showMessageDialog(null, "Erro : " + erro);

    }
}

e esse e o metodo para cadastrar na classe itemDAO

public void cadastraItem(ItemVenda obj){
    
       try {

        String sql = "insert into tb_itensvendas (venda_id, produto_id,qtd,subtotal) values (?,?,?,?)";
      
        PreparedStatement stmt = con.prepareStatement(sql);

        stmt.setInt(1, obj.getVenda().getId());
        stmt.setInt(2, obj.getProduto().getId());;
        stmt.setInt(3, obj.getQuantidade());
        stmt.setDouble(4, obj.getSubtotal());

        stmt.execute();
        stmt.close();

       

    } catch (Exception erro) {

        JOptionPane.showMessageDialog(null, "Erro : " + erro);

    }

Formulario de pagamento,
o erro acontece apos eu clicar o botãoo finalizar pagamento.
Tem hora que funciona, ai quando da o erro tenho q excluir o banco de dados e o usuario e criar bd de novo, e entao funciona ate da o erro novamente.
a seguir botão finalizar pagamento.

private void btnFinalizarVendaActionPerformed(java.awt.event.ActionEvent evt) {                                                  
    // 
    double pCartao, pCheque, pDinheiro, totalPago, totalVenda, troco;
    pCartao = Double.parseDouble(txtCartao.getText());
    pCheque = Double.parseDouble(txtCheque.getText());
    pDinheiro = Double.parseDouble(txtDinheiro.getText());
    totalVenda = Double.parseDouble(txtTotal.getText());

    //Calcularo total e o troco
    totalPago = pCartao + pCheque + pDinheiro;
    troco = totalPago - totalVenda;
    txtTroco.setText(String.valueOf(troco));

    Vendas objv = new Vendas();
    //Dados do cliente (cliente_id)
    objv.setCliente(cliente);

    ///data da venda
    Date agora = new Date();
    SimpleDateFormat dataEUA = new SimpleDateFormat("yyyy-MM-dd");
    String datamysql = dataEUA.format(agora); 

    objv.setDataVenda(datamysql);

    //Total da venda
    objv.setTotalVenda(totalVenda);
    objv.setObservacoes(txtObservacoes.getText());

    VendasDAO dao_v = new VendasDAO();
    dao_v.cadastrarVenda(objv);

    //Retorna o id da ultima venda realizada
    objv.setId(dao_v.retornaUltimaVenda());

// Cadastrando os produtos na tabela itemvendas

for (int i = 0; i < carrinho.getRowCount(); i++) {

        int quantidadeEstoque, quantidadeComprada, quantidadeAtualizada;
        Produtos objp = new Produtos();
        ProdutosDAO dao_produto = new ProdutosDAO();

        ItemVenda item = new ItemVenda();
        item.setVenda(objv);

        objp.setId(Integer.parseInt(carrinho.getValueAt(i, 0).toString()));
        item.setProduto(objp);
        item.setQuantidade(Integer.parseInt(carrinho.getValueAt(i, 2).toString()));
        item.setSubtotal(Double.parseDouble(carrinho.getValueAt(i, 4).toString()));

       
        //Baixa no estoque
        
         quantidadeEstoque = dao_produto.retornaEstoqueAtual(objp.getId());
        quantidadeComprada = Integer.parseInt(carrinho.getValueAt(i, 2).toString());
        quantidadeAtualizada = quantidadeEstoque - quantidadeComprada;
        
        dao_produto.baixaEstoque(objp.getId(), quantidadeAtualizada);         

        ItemVendaDAO daoitem = new ItemVendaDAO();
        daoitem.cadastraItem(item);
        
        

    }

A primeira impressão é que está tentando salvar uma venda com um cliente_id que não existe no BD.

É isso que achei tambem, mas no primeiro jPanel o cliente é selecionado digitando o cpf e dou enter e é preenchido automaticamente como nome do cliente,
mais abaixo tem um outro jPanel que digito o codigo do produto e tambem. faltando somente digitara quantidade.

por fim clico em adicionar e itens vão para um terceiro jPanel, que é o carrinho de compras, ai clico em pagamento,

logo depois abri a tela de pagamento com o botão de finalizar venda e é nesse momento que da o erro, você acha que se eu colocar validadores no primeiro jPanel, para impedir campos nulo resolve?

Para melhor ilustração segue as imagens dos passos.

Na imagem abaixo e que aparece o erro,

Porem algumas vezes finalizo o passo 7, e a venda e salva sem da erro, mostrando a mensagem Venda registrada com sucesso, ao repetir o processo aparece o erro.

botão pesquisar do form da primeira imagem

 // Pesquisa por cpf
     private void btnBuscaClienteActionPerformed(java.awt.event.ActionEvent evt) {                                                
    // Pesquisa por cpf
    Clientes obj = new Clientes();

    ClientesDAO dao = new ClientesDAO();
    obj = dao.buscaPorCpf(txtCpf.getText());
    txtNome.setText(obj.getNome());
    
}  

e o metodo da classe vendao dao para buscar por cpf

public Clientes buscaPorCpf(String cpf) {
    try {
        //1 passo - criar o sql , organizar e executar.
        String sql = "select * from tb_clientes where cpf = ?";
        PreparedStatement stmt = con.prepareStatement(sql);
        stmt.setString(1, cpf);

        ResultSet rs = stmt.executeQuery();
        Clientes obj = new Clientes();

        if (rs.next()) {

            obj.setId(rs.getInt("id"));
            obj.setNome(rs.getString("nome"));
            obj.setRg(rs.getString("rg"));
            obj.setCpf(rs.getString("cpf"));
            obj.setEmail(rs.getString("email"));
            obj.setTelefone(rs.getString("telefone"));
            obj.setCelular(rs.getString("celular"));
            obj.setCep(rs.getString("cep"));
            obj.setEndereco(rs.getString("endereco"));
            obj.setNumero(rs.getInt("numero"));
            obj.setComplemento(rs.getString("complemento"));
            obj.setBairro(rs.getString("bairro"));
            obj.setCidade(rs.getString("cidade"));
            obj.setUf(rs.getString("estado"));
        }

        return obj;

    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, "Cliente não encontrado!");
        return null;
    }
}

Sim.

Penso que pode ser erro no sql, como voce está utilizando a FK