Pessoal, estou utilizando JPA com Hibernate, gostaria de saber se tem como
dizer para a JPA que alterações em uma entidade gerenciada só seja enviada
ao banco quando o método de atualização for chamado?
[RESOLVIDO] Controlar momento que o JPA manda informações para o banco?
13 Respostas
Procure pelas funções de callback:
http://ericogr.wordpress.com/2008/04/28/usando-callback-listeners-jpa/
Na verdade não é isso que preciso, o problema aqui é o seguinte
tenho uma entidade gerenciada, em uma tela de edicao, quando o usuario
faz algumas alterações e resolve cancelar como a entidade esta gerenciada
as alterações ja foram para o banco, eu gostaria de saber se tem uma forma de dizer
ao hibernate para ele não atualizar até o metodo merge ser chamado, pois desta forma
se o botao de salvar nao forma chamada as alterações feitas não seram levadas para o banco.
seta o “autoCommit” como false e tenha o controle delas.
Só presta atenção, porque agora toda transação para ser efetivada (gravada no banco), voce precisará obrigatoriamente fazer um “commit”.
e é exatamento isso que não quero fazer, até pq aqui usamos container EJB e não fazemos commit
Se vc usa um EJB container, ele faz commit por você. Não tem essa dos dados entrarem sozinho para o banco.
O que vc está falando não faz sentido. Se vc usa JPA sem EJB container, é uma coisa. Se vc usa com, é outra.
A menos que vc esteja usando JPA na sua camada web e fazendos o commit lá. E isso é errado por design.
Explique melhor.
é acho q vc não entendeu mesmo não.
Como utilizo o container a entidade fica gerenciada, com a entidade gerenciada qualquer alteração nela
o entityManager ja reflete no banco, isso a propria especificação diz que na hora q o gerenciador bem entender
as alterações vão para o banco, o que eu preciso é trabalhar com a entidade gerenciada mais evitar que as alterações
vão para o banco até que eu chame o merge.
é acho q vc não entendeu mesmo não.Como utilizo o container a entidade fica gerenciada, com a entidade gerenciada qualquer alteração nela
o entityManager ja reflete no banco, isso a propria especificação diz que na hora q o gerenciador bem entender
as alterações vão para o banco, o que eu preciso é trabalhar com a entidade gerenciada mais evitar que as alterações
vão para o banco até que eu chame o merge.
Vc não está interpretando corretamente a especificação. A espeficicação fala isso, mas depois que o commit acontece.
Ou seja, vc dar commit não fignifica que o manager vai gravar naquele momento, mas para a sua aplicação vai.
Alterar um campo na entidade não altera automáticamente no banco. Isso seria absurdo, inutil e estúpido.
Primeiro vc pega o objeto. Vc dá um set alguma coisa. ai vc dá merge/save. e depois vc comita. se vc não der o merge/save nada acontece. se vc não comitar nada acontece. quando o usuário dá cancel, vc simplesmente não dá o merge/save.
Cara, aqui utilizamos container EJB, logo não é preciso realizar commit o container ja faz isso.
Quando vc utiliza container, basta pegar a entidade e chamar um metodo set dela, ou entao
se vc tiver uma tela que usa essa entidade e fizer alguma requisição ajax nesse campo, como
a entidade esta gerenciada, quando a requisição termina a alteração ja é refletida no banco.
Olha cara…euy não estou entendo muito bem a sua necessidade.
De qualquer forma, acho que isso pode te ajudar:
http://docs.sun.com/source/816-6101-10/ptrans.htm
https://disciplinas.dcc.ufba.br/pub/MAT167SD/TutTransactions/Transactions.pdf
pra ficar no historico, colocando flush-mode="manual"
que funciona somento se o hibernate for o provider
ele diz que alterações na entidade mesmo quando esta
for gerenciada, as alterações só seram realizadas se um flush
for feito.
Cara, aqui utilizamos container EJB, logo não é preciso realizar commit o container ja faz isso.
Vc não precisa dar o commit, mas precisa dar o merge/save!
simplesmente fazendo o set não altera em nada o estado do sistema.
Basta não fazer o merge/save e os dados , mesmo depois de setados via set, não serão atualizados no banco.
Se vc alterar a propriedade de um objeto e chamar o flush do EntityManager, será realizado o update sem necessidade de chamar o merge.
É isso que vc quer?
Vc não precisa dar o commit, mas precisa dar o merge/save!
simplesmente fazendo o set não altera em nada o estado do sistema.Basta não fazer o merge/save e os dados , mesmo depois de setados via set, não serão atualizados no banco.
Kra o merge pega as alterações de uma entidade e leva para o banco e retorna
uma entidade gerenciada, a minha entidade JÁ esta gerenciada, logo não preciso de merge
para que suas alterações sejam levadas para o banco, elas seram levadas quando o entity manager bem entender
assim como diz a especificação. Agora se vc usa JPA e altera uma entidade gerenciada e ainda assim
precisa fazer merge, vc deve ta fazendo alguma coisa de errado até pq o conceito de estar gerenciada é esse.
Mais de qualquer forma ja resolvi o problema o flush-mode=“manual” indica ao hibernate que mesmo para uma entidade gerenciada
ele so faça as alterações quando o método flush() for chamado manualmente.
Recomendo essa leitura aqui: http://docs.jboss.org/seam/2.1.0.CR1/reference/en-US/html/persistence.html#d0e6811
ela explica com detalhes como utilizar o flush-mode=“manual” e foi ela que ajudou a resolver meu problema.