Por acaso alguém sabe como faço pra fazer um update em uma chave primária com o hibernate?
flw
Por acaso alguém sabe como faço pra fazer um update em uma chave primária com o hibernate?
flw
Não sei se entendi bem o que vc quer, mas, p/ atualizar um registro vc pode fazer +ou- isso :
Session s = HibernateFactory.getSession();
Transaction tx = null;
try {
tx = s.beginTransaction();
s.update( p ); //p objeto produto
s.flush();
tx.commit();
} catch (RuntimeException e) {
if (tx != null)
tx.rollback();
//e.printStackTrace();
throw new RuntimeException(e.getMessage());
} finally {
s.close();
}
Não é isso.
Quero trocar o valor da chave.
Ex.:
Tabela
-------
campo1 pk
campo2 pk
campo3
Imagine o seguinte:
campo1 pk = 1
campo2 pk = 2
campo3 = "teste"
Agora quero alterar o valor do campo1 de 1 para 5
Esse é o problema.
O ID de um objeto é a identidade dele, quando se altera o id altera-se na verdade a identidade do objeto e isso implicaria na altualização ou não das dependencias bem como em um erro de constraint. Acho que o hibernate leva isso bem ao pé da letra, portanto se vc precisa disso jogue o objeto antigo fora (delete) e adicione um novo objeto com o novo Id.
Pode não ser a solução dos sonhos, mas se vc pensar bem vai ver que faz sentido.
Concordo !!!
Imagine que vc pediu, quero o produto de codigo = 1
ele traz p/ vc
qdo vc muda o codigo de 1 p/ 5 ele vai procurar o registro na base e não vai encontrar , acho que vc teria que excluir e incluir de novo, fora as dependências com outras tabelas…
Mas se eu achar alguma coisa , dou um toque !!!
Já pensei e implementei isso , mas, isso implica em excluir todas as dependencia, dessa forma fica complicado.
Queria uma forma de alterar a pk e as dependências em cascata.
flw,
Tentei fazer e olha a msg que dá
Unexpected row count: 0 expected: 1
está dando a mesma mensagem p/ vc ???
porque vc está precisando fazer isso ???
Sinceramente, me diz qual a real necessidade de atualizar um PK? Não consigo entender onde isso seja necessário… :roll:
Tem algum banco de dados que permite fazer isso? @.@
No SQLServer nas poucas vezes que fiz cagada e precisei alterar o ID, tive que alterar a tabela retirando a marcação de PK na coluna, alterar o valor e então marcar como PK de novo.
Oxe, isso por aqui é conhecido como gambiarra :lol:
Maurício Linhares. Gambiarra? Caro colega, deixo aberto para vc formular sua sugestão .
LIPE. Quanto ao banco de dados:
Estou utilizando o Postgresql e este suporta cascateamento de update ou delete para os relacionamentos. Sei que isso fere questões referentes a portabilidade, mas, antes limitar a gama de bancos do que limitar as funcionalidades do sistema .
vmorikawa. Isso acontece porque vc tentou fazer um update com a id já alterada. Dessa forma como ele não encontrou nenhum registro para o update lançando essa exception.
Na session tem um metodo sobrecarregado do update que recebe o objeto + a chave, só que ele altera apenas os dados que não são chave.
O update poderia ser feito com hql, mas esse tem várias restrições não atendendo a necessidade.
volnei. Quanto ao caso de uso é o seguinte:
Não sei se alguém já trabalhou com estrutura de equipamentos, mas, vou tentar descrever brevemente:
Imagine que tenha a seguinte estrutura de objetos mapeados:
Estrutura
---------
EstruturaPK id
...
List itensSubstituicao
EstruturaPK
-----------
Produto produtoPai
Produto componente
Long item
Produto
-------
Long codigo
String descricao
...
ItemSubstituicao
----------------
Estrutura
Produto componenteSubstituivel
...
Isso é utilizado para se montar a estrutura de um produto fabricado. Dessa forma obtem-se vários valores como peso total da estrutura referente ao produto final e outros.
Agora o caso de uso:
Imagine que o componente utilizado na montagem da estrutura do produto não seja mais fabricado. O novo produto designado para substituir esse é cadastrado e as estruturas que contem o componente antigo devem ser atualizadas. Por coincidencia, e para correta modelagem e integridade do BD, este faz parte da é chave primária .
Sugestões são bem vindas.
flw
Olha, eu acho bem mais fácil colocar o novo produto na base e fazer os outros produtos que dependem dele apontarem pra ele, do que fazer um cascateamento de chaves, especialmente usando Hibernate, onde trafegar e montar um grafo de objetos é tão complicado quanto chamar métodos get/set.
E eu disse que era gambiarra, porque pra mim parece gambiarra mesmo, não vejo nenhuma dificuldade de retirar a referência pra o objeto que não é mais produzido e colocar uma referência pro outro objeto lá.
Como você explicaria essas suas tabelas em objetos?
A questão é que não se tem produtos apontando para produtos e sim objetos que os relacionam e que no mundo relacional seguindo as regras de normalização ficam dispostos da forma que mostrei.
Reconheço a complexidade em mapear o mundo relacional para o OO e também que nosso companheiro hibernate é o cara nesse quesito.
Quanto a montar novamente a estrutura com o novo produto, isso, impactaria em todas as dependencias, ficando inviável.
Também não via problema algum até esbarrar nesse caso. Tirar referência é fácil, o problema é o que isso vai gerar ao ser traduzido para o relacional.
[quote=fabriciogiordani]
Também não via problema algum até esbarrar nesse caso. Tirar referência é fácil, o problema é o que isso vai gerar ao ser traduzido para o relacional.[/quote]
Mas não é o Hibernate que vai fazer isso pra você? Ele provavelmente não vai se enganar
Pois é, como falei acima e como o vmorikawa acabou testando, o hibernate monta o update baseado na id do objeto. Dessa forma se for fazer um update(objeto) com a chave alterada o hibernate vai tentar montar um update com where baseado nos valores da id do objeto do parâmetro, o que vai resultar em uma exception, pois, não vai encontrar nenhum registro para tal alteração.
Tentei então utilizar update(objeto, id), mas, esse mesmo que no objeto a id esteja alterada e passe a id antiga por parâmetro a qual ele teria que utilizar para montar o where para o update, ele monta o where, mas não inclui os campos chave no update.
Mas não foi esse o modo que eu disse, eu falei sobre atualizar os objetos que apontam pra esse objeto aí, não o contrário.
Pense em objeto, não em tabelas
É bem mais fácil atualizar as referências.
E outra vez, como você modelou isso em objetos?