Usando o hibernate 3 qual a solucao que voces indicam para fazer um update de determinados campos de um objeto?
Seria mais o menos o seguinte:
Produto p = new Produto();
p.setId(15L);
p.setNome(“Alterando…”);
s.update§;
O problema do update e hque ele atualizaria tambem o campo ‘descricao’ que eu nao desejo alterar. O proprio merge nao da conta do recado uma vez que o produto que esta sendo utilizado eh um new de Produto.
Alguma sugestao?
Entao ricardo, o problema eh que fazendo o load, na hora de dar o update ele primeiro faz um select no banco. Esse select podefria ser ignorado se eu ja dissesse pra ele quais campos foram alterados. Mas pelo que analisei isso eh impossivel. Vou fazer uma sugestao la
Você pode fazer isso extendendo a classe do hibernate que decide isso.
A idéia é simples, quando a entidade sofrer attachment você guarda isso e na hora de verificar quais campos alterar, pega apenas os != null.
Vale lembrar que. Vale lembrar que pra isso funcionar o hibernate tem que estar configurado para gerar update somente para os campos alterados.
A regra do != null eh muito fraca. As vezes eu alterei o campo justamente para null pq quero gravar null no banco de dados…
Acho que a saida eh implementar um metodo do tipo proxyLoad na session, nao sei o nome, sei que esse nome nao eh bom, mas nao sei melhor. Assim:
Produto p = session.proxyLoad(Produto.class, id);
Ai eu chamo os setters desse produto. Com isso, o hibernate (que retornou um objeto adulterado) fica sabendo quais setters eu chamei para fazer o update desses campos.
Se tenho um objeto com muitas propriedades carregado num formulário e o usuário altera apenas uma informação, da maneira que sugeri preciso enviar para o servidor um objeto apenas com a PK e alteração.
Da forma que sugeriu seria necessário trafegar o objeto inteiro.
Sem contar que o Hibernate não vai cachear as queries, o que também no nosso caso vira um problema.
Noel, no caso ele so iria enviar os campos que foram alterados.
Louds, onde eu sugiro isso la? No jira? Bem que eu podia implementar viu… nunca vi o hibernate por tras, alguem ja colocou a mao nele?
Lipe, o problema eh que a aplicacao eh web, entao nao tenho o objeto persistido por natureza, uma vez que a requisicao eh asincrona. Claro que tenho que levar em conta o problema do locking, nao tinha pensado direito como fazer isso funcionar nesse proxyLoad ou algo do genero.
Tenho duas opcoes: a de sempre, de fazer o load e alterar os campos. Ou a de assumir a responsabilidade. Hummmm… acho que vou tentar a segunda mesmo (pra ter o que fazer por algum tempo)
Sérgio, acho que ficou perdido pois não expliquei que este projeto não é web. Então são objetos (que muitas vezes são bastante grandes) serializados que ficam indo para lá e para cá, não strings no http request.
Um exemplo simples (que nem requeriria a estrutura que estamos utilizando) para esclarecer:
cliente pede para o servidor o objeto Pessoa com ID=1
Pessoa é passado pela rede e popula o formulário
cliente altera o nome da Pessoa
cliente envia um objeto Pessoa apenas com o Nome e Id populados para servidor
servidor sabe que apenas nome foi alterado
servidor pega uma instancia persistente de Pessoa com ID=1 (lembre-se do lazy loading do Hibernate)
sérgio, como disse precisamos fazer o select before update de qualquer maneira para pegar o timestamp e informar para o cliente qualquer campo que tenha sido alterado desde que ele carregou aquele registro.
E sério, um selectzinho de nada melhor que passar alguns vários kbytes a mais em todo santo update.
Quando queremos fazer o select como o Lipe falou nao tem problema nenhum. O hibernate oferece varios tipos de locking.
Mas quando preciso fazer fine-tuning da aplicacao o select a mais que o hibernate possui para fazer a verificacao da versao ou timestamp deveria ser configuravel.
Tentei a anotacao selectBeforeUpdate=false. Funciona. Ele nao faz o select
Mas ai ele da update em todos os campos.
Ai tentei com selectBU=false e dynamicUpdate=true. Ele nao faz select mas faz update de todos os campos novamente.
Acho que nesse caso de ter uma instancia transiente e ter que dar um update somente nesses campos nao adianta
e na hora de enviar o objeto de volta os campos q seriam
enviados, alem dos q foram alterados, iriam ser null, nao sei como isso trafega pela rede, mas acho q pelo fato de ser null, não seriam dados significativos p/ rede …