Duplicação de Primary Key

27/02/2013

7

Fala galera, estava procurando um tópico sobre este problema, achei, mais o cara conseguiu resolver, mais não postou a resolução, o meu eh bem parecido com o dele.. estou fazendo uma aplicação em java, e estou com problemas em chave duplicada, ou seja, esse erro --> Duplicate entry '18' for key 'PRIMARY' 18, eh a id que está tentando inserir dois tipos de produtos ao mesmo tempo, fala que a venda foi cadastrada com sucesso, mais gera essa exceção..

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '18' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)





O meu código da minha classe Vendas:





public class VendasControl {

PreparedStatement pst;
ResultSet rs;

String cadastraVenda = "INSERT INTO VENDAS (ID_VENDAS, ID_PRODUTOS, ID_ALUNOS, DATA_VENDAS, QUANTIDADE) "
+ " VALUES (?,?,?,?,?)";


String buscaUltimoCodigo = "SELECT MAX(ID_VENDAS) AS ID_VENDAS FROM VENDAS";


public VendasControl(){

}

public int buscarCodigoUltimaVenda(){
try{
ConexaoBD bd = new ConexaoBD();
pst = (PreparedStatement) bd.conectar().prepareStatement(buscaUltimoCodigo);
rs = pst.executeQuery();
if (rs.last()){
return rs.getInt("id_vendas");
}
bd.desconectar();
} catch (SQLException ex){
ex.printStackTrace();
}
return 0;
}

public void CadastrarVenda(VendasBean venda){

try{
ConexaoBD bd = new ConexaoBD();
pst = (PreparedStatement) bd.conectar().prepareStatement(cadastraVenda);
pst.setInt(1, venda.getId());
pst.setInt(2, venda.getIdProduto());
pst.setInt(3, venda.getIdAluno());
pst.setDate(4, venda.getDataVenda());
pst.setInt(5, venda.getQuantidade());
pst.executeUpdate();
bd.desconectar();
}catch (SQLException ex){
ex.printStackTrace();
}

}

}


Código que cadastra a venda:

private void cadastrarVenda(){
if(venda.size() == 0){
JOptionPane.showMessageDialog(this, "Inclua pelo menos um produto!");

}else{
try{
VendasControl vc = new VendasControl();
SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd"); //formata o campo para datas
java.util.Date d = new java.util.Date();
Date data = Date.valueOf(formato.format(d)); //data da venda
int codigo = vc.buscarCodigoUltimaVenda() + 1;
for (int i = 0; i < venda.size(); i++){
venda.get(i).setIdAluno(alunos.get(cbAlunos.getSelectedIndex()).getId());
venda.get(i).setDataVenda(data);
venda.get(i).setId(codigo);
vc.CadastrarVenda(venda.get(i));
}
JOptionPane.showMessageDialog(this, "Venda cadastrada com sucesso!");
}catch (Exception ex){
JOptionPane.showMessageDialog(this, "Erro ao cadastrar Venda!");
}
}
}


Aqui a imagem do que eu to falando !

[url]http://img171.imageshack.us/img171/913/print6lu.png[/url]

Quando eu clico em finalizar, é quando gera esse erro que eu falei acima !
Obs: Não importa o produto, pode ser de nome diferente, id diferente, se eh dois ou mais, da esse erro, agora se for um produto, nem gera erro e vai de booa !

Agradeço desde já quem puder me ajudar ! Obrigado e até mais :)
Responder

Posts

27/02/2013

Danilo Gomes

Cara, é possível usar um campo auto increment no ID_VENDAS?
Responder

27/02/2013

Danilo Gomes

Outra coisa, já tentou debugar e ver se os valores das variáveis estão de acordo com o esperado?
Responder

27/02/2013

Danilo Gomes

Cara, abstraindo as perguntas acima, existe um erro de lógica mesmo.


int codigo = vc.buscarCodigoUltimaVenda() + 1; // O MESMO ID SERÁ UTILIZADO NO FOR ABAIXO
for (int i = 0; i < venda.size(); i++){
venda.get(i).setIdAluno(alunos.get(cbAlunos.getSelectedIndex()).getId());
venda.get(i).setDataVenda(data);
venda.get(i).setId(codigo);
vc.CadastrarVenda(venda.get(i));
}



Veja que está utilizando o mesmo ID dentro do FOR, teria que repetir essa chamada no FOR também.
Responder

27/02/2013

Vinicius Gomes

como assim repetir essa chamada no for !? não entendi !
Responder

27/02/2013

Danilo Gomes

Não faria muito sentido né? rs

Então, qual a chave primária desta sua tabela? É o ID_VENDAS? Apenas ele?
Responder

27/02/2013

Danilo Gomes

Minhas sugestões iniciais foram equivocadas porque, pelo que entendi, esta tabela é um relacionamento.

O que está acontecendo, imagino eu, é que a chave primária refere-se apenas ao ID_VENDAS.
Quando vai alocar um segundo produto utiliza (logicamente) o mesmo ID_VENDAS, violando a constraint.

Nesse caso, pode modificar a chave primária para que seja composta por outros IDS.

A chave pode ser {ID_VENDAS E ID_PRODUTOS}.

Dessa forma pode cadastrar mais de um produto para uma mesma venda.
Responder

27/02/2013

Vinicius Gomes

Então me ajuda aqe, isso qe vce falou por ultimo fez sentido, mais é qe minha lógica não está muito boa..

essa é minha tabela vendas

create table vendas(

id_vendas int default null,
id_produtos int (50) default null,
id_alunos int (25) default null,
Data_vendas DATE default null,
quantidade int (10) default null,
primary key (id_vendas)
);
ALTER TABLE `vendas` ADD CONSTRAINT `fk_id_produtos`
FOREIGN KEY ( `id_produtos` )
REFERENCES `produtos` (`id_produto`) ;

ALTER TABLE `vendas` ADD CONSTRAINT `fk_id_alunos`
FOREIGN KEY ( `id_alunos` )
REFERENCES `alunos` (`id`) ;

ALTER TABLE vendas MODIFY id_vendas int NULL AUTO_INCREMENT;

Responder

27/02/2013

Vinicius Gomes

E como eu modificaria a chave primária para que seja composta por outros IDS ?
Responder

27/02/2013

Danilo Gomes

Primeiro tem que remover o status de primary key de ID_VENDAS

Para remover a chave primária existe, não tenho certeza, mas acredito que seja:
ALTER TABLE tabela DROP PRIMARY KEY; 


Depois deve-se fazer algo do gênero:
ALTER TABLE  nomedatabela ADD CONSTRAINT PRIMARY KEY (campo1, campo2, ... campo N);


Responder

27/02/2013

Danilo Gomes

Se puder recriar a tabela é ainda mais fácil:

create table vendas(

id_vendas int default null,
id_produtos int (50) default null,
id_alunos int (25) default null,
Data_vendas DATE default null,
quantidade int (10) default null,
primary key (id_vendas, id_produtos)
);
Responder

27/02/2013

Vinicius Gomes

Me passa seu email pra gente conversar melhor, se você puder, é claro !

Desde já agradeço a sua ajuda, e mais tarde eu testo o que vcê falou !

Abraçoo, té mais !
Responder

27/02/2013

Vinicius Gomes

Minha ultima duvida !
Eu vou deixar o id_produtos como chave estrangeira tbm ? ou isso não é possivel ?

abrass
Responder

27/02/2013

Danilo Gomes

Você DEVE deixar como chave estrangeira também para manter a integridade.

Qualquer coisa pode postar aí no fórum que a gente ajuda.
Responder

27/02/2013

Danilo Gomes

Olhando agora como o tópico desenvolveu-se, faria mais sentido ficar lá no MySQL né? rs
Responder

28/02/2013

Vinicius Gomes

A id_vendas não tinha que ser auto increment ? e a id_produtos ?

Pode colocar la no forum de MySQL sim, mais nem sei como qe coloca ! hsuahsua
Responder