hibernate update/merge  XML
Índice dos Fóruns » Desenvolvimento Web
Autor Mensagem
Guilherme Silveira
Administrador

Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline

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(p);


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?

Abraco

Guilherme

This message was edited 2 times. Last update was at 15/07/2005 17:43:21


-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
[Email] [WWW] [MSN]
ricardolecheta
GUJ Master
[Avatar]

Membro desde: 17/05/2003 13:42:10
Mensagens: 1486
Localização: Curitiba
Offline

Vc não pode fazer um load antes? Então se alterar o objeto, quando vc fizer commit o hibernate fará update somente naqueles campos que vc alterou.


Ricardo R. Lecheta
Livro - Google Android (português)
http://www.livroandroid.com.br/
http://livroandroid.blogspot.com/
http://www.livetouch.com.br/
Guilherme Silveira
Administrador

Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline

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

Abraco

Guilherme

-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
[Email] [WWW] [MSN]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

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.

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
Guilherme Silveira
Administrador

Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline

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:

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.

-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
[Email] [WWW] [MSN]
Filipe Sabella
GUJ Expert

Membro desde: 12/03/2003 11:25:57
Mensagens: 4680
Offline

Chato isso mesmo. Resolvi assim:
- via AOP, guardo numa Collection quais os campos alterados
- faço load do Objeto da Database
- no objeto persistente altero os campos que foram modificados

Resolveu o problema. Quanto ao load "extra" ele já ocorreria pela necessidade de optimistic-locking.

This message was edited 2 times. Last update was at 14/07/2005 15:44:21


Former LIPE.
[ICQ]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Hmm, essa solução é realmente bem melhor Guilherme, sugere isso pra eles.

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
jack_-_ganzha
JavaEvangelist
[Avatar]

Membro desde: 31/03/2003 13:18:12
Mensagens: 315
Localização: Recife - Pernambuco
Offline

Mapear com dynamic-update não resolve? Do manual:
dynamic-update (optional, defaults to false): Specifies that UPDATE SQL should be generated at runtime and contain only those columns whose values have changed.

<editado>Esquece, agora é que vi o seu trecho de codigo.</editado>
valeuz...

This message was edited 1 time. Last update was at 14/07/2005 16:59:18


Marcos Silva Pereira

http://www.javafree.org
http://marcospereira.wordpress.com
[MSN] [ICQ]
Filipe Sabella
GUJ Expert

Membro desde: 12/03/2003 11:25:57
Mensagens: 4680
Offline

Hum, no nosso caso não cara.

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.

Former LIPE.
[ICQ]
noelrocha
Thread.start()

Membro desde: 12/07/2005 12:46:51
Mensagens: 32
Offline

nao entendi muito bem a ideia do proxyLoad(...) ...

ele traria o objeto apenas com o ID preenchido?


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 ...

foi um palpite ...

[]´s
________
Noel R. Morais
Guilherme Silveira
Administrador

Membro desde: 14/08/2002 10:09:26
Mensagens: 1096
Localização: Sao Paulo
Offline

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)

Valeu gente

Guilherme

-------------------------------------------------------
Guilherme Silveirahttp://blog.caelum.com.br
[Email] [WWW] [MSN]
Filipe Sabella
GUJ Expert

Membro desde: 12/03/2003 11:25:57
Mensagens: 4680
Offline

Ah ... web ... medo.

Former LIPE.
[ICQ]
saoj
JWizard
[Avatar]

Membro desde: 09/03/2004 23:34:46
Mensagens: 2667
Localização: Chicago, EUA
Offline

LIPE wrote:Chato isso mesmo. Resolvi assim:
- via AOP, guardo numa Collection quais os campos alterados
- faço load do Objeto da Database
- no objeto persistente altero os campos que foram modificados

Resolveu o problema. Quanto ao load "extra" ele já ocorreria pela necessidade de optimistic-locking.


Fiquei perdidão nesse post !!!

O Hibernate não faz update só nos campos que foram alterados ?

O problema do Guilherme é que o objeto estava detached, então a session não tinha nenhuma informação e gravava tudo.

O que o Guiherme quer é dar um update num registro sem ter que carregá-lo do database, pois o objeto pode ser gigantesco.

E quer dar update só na coluna que ele alterou e não em tudo.

E aí, como resolve isso ?

A solução do Lipe não está fazendo o load do database !?

This message was edited 3 times. Last update was at 15/07/2005 14:37:38


Sergio A Oliveira Jr. - saoj

ExperiMENTA:

Mentawai = http://www.mentaframework.org - Full-stack Java Web Framework com Configuracão Programática
MentaQueue = http://mentaqueue.soliveirajr.com - Queue de alta-performance.
MentaLog = http://mentalog.soliveirajr.com - Non-intrusive, fast, garbage-less, colored and straightforward logging
MentaBean = http://mentabean.soliveirajr.com - Tiny ORM with SQL Builder
MentaRegex = http://mentaregex.soliveirajr.com - Perl-style regex for Java.
MentaContainer = http://mentacontainer.soliveirajr.com - Straightforward IoC, DI e Auto-Wiring
Space4J = http://www.space4j.org - Banco-de-dados de Objetos em Memória
Options-Lib = https://github.com/saoj/options-lib - Ruby classes para ter acesso as opcoes do Yahoo Finance
Selleto = http://www.selleto.com.br
Flipinion = http://www.flipinion.com
Kawai = http://www.kawaiwiki.org


[Email] [WWW]
Filipe Sabella
GUJ Expert

Membro desde: 12/03/2003 11:25:57
Mensagens: 4680
Offline

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)
- servidor faz algo como pessoa.setNome( nome )
- objeto atualizado no banco

Former LIPE.
[ICQ]
saoj
JWizard
[Avatar]

Membro desde: 09/03/2004 23:34:46
Mensagens: 2667
Localização: Chicago, EUA
Offline

Valeu Lipe pela pronta resposta! Ter um Hibernate guru como vc pra me ajudar agora no início é de grande valia.

O problema está aqui:

LIPE wrote:
- servidor pega uma instancia persistente de Pessoa com ID=1 (lembre-se do lazy loading do Hibernate)


Não quero carregar nada do banco de dados.

Quero apenas fazer um update no campo age sem carregar o objeto profile inteiro.

Entendi que isso é perigoso, pois não vou saber se alguma outra transação alterou o campo age também e posso acabar sobre-escrevendo a alteração dela.

Talvez o Hibernate exija esse load sempre para não ter os problemas de concorrência. Sei lá...

E aí? Consigo fazer um update num único campo de um registro sem ter que dar um load nele ou não ?

Sergio A Oliveira Jr. - saoj

ExperiMENTA:

Mentawai = http://www.mentaframework.org - Full-stack Java Web Framework com Configuracão Programática
MentaQueue = http://mentaqueue.soliveirajr.com - Queue de alta-performance.
MentaLog = http://mentalog.soliveirajr.com - Non-intrusive, fast, garbage-less, colored and straightforward logging
MentaBean = http://mentabean.soliveirajr.com - Tiny ORM with SQL Builder
MentaRegex = http://mentaregex.soliveirajr.com - Perl-style regex for Java.
MentaContainer = http://mentacontainer.soliveirajr.com - Straightforward IoC, DI e Auto-Wiring
Space4J = http://www.space4j.org - Banco-de-dados de Objetos em Memória
Options-Lib = https://github.com/saoj/options-lib - Ruby classes para ter acesso as opcoes do Yahoo Finance
Selleto = http://www.selleto.com.br
Flipinion = http://www.flipinion.com
Kawai = http://www.kawaiwiki.org


[Email] [WWW]
 
Índice dos Fóruns » Desenvolvimento Web
Ir para:   
Powered by JForum 2.1.8 © JForum Team