Blog do Urubatan
msgbartop
Desenvolvedor, Arquiteto, Palestrante, Coordenador do RSJUG, Patinador e Blogger
msgbarbottom

20 Apr 07 Dica rápida: desabilitando a persistencia automática no hibernate

Bom, não sei se alguem mais ja teve problemas com isto …
mas eu estava desenvolvendo um wizard em uma aplicação web, onde por diversos motivos, o wizard todo precisava utilizar a mesma sessão do hibernate …
O problema é que o hibernate tem mania de quando se altera algum objeto, e a sessão ainda estiver aberta, ele persiste as propriedades alteradas mesmo que você não chame um update …
Neste caso especifico, eu tinha ja montado relacionamentos entre objetos persistentes (que vieram do banco), e objetos ainda não existentes no banco, e que ainda não estavam prontos para serem persistidos …

Existiam diversas transações durante este wizard, e em algum momento ele fazia um flush antes de iniciar uma transação e por causa do “persistence by reachability”, ele tentava salvar também os objetos que ainda não existiam no banco de dados, mas ja estavam associados a um objeto que havia sido lido do banco de dados …
e como este objeto tinha algumas propriedades not null, que ainda não haviam sido setadas, estourava um erro …
este erro até que não foi ruim, eu perdi o dia inteiro para resolver este erro chato, mas seria pior ainda se ele inserisse os dados no banco antes de eu manda-lo fazer isto …

pois seguindo com a dica: se algum de vocês estiver em uma situação parecida com esta, a solução é mais fácil do que parece, considerando que o Hibernate não tem uma chave que permita desabilitar esta “feature” de salvar as coisas antes de você mandar ele fazer isto …

Foi só garantir que todos os metodos de leitura fossem executados dentro de uma transação “read-only” :D
se o spring estiver gerenciando as transações para vocês, é só colocar um:

@Transactional(readOnly=true)

nos metodos de leitura …
se for a API nativa do Hibernate ai a unica forma que encontrei foi setar o flushMode da session para NEVER ja que é exatamente esta a implementação do spring …

aparentemente isto solucionou o meu problema :D Espero que a dica ajude alguem a perder menos tempo com isto do que eu perdi …

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Tags: ,

Reader's Comments

  1. |

    não é mania do hibernate, é o correto :-)
    depois de carregar o objeto, vc pode fazer session.evict(obj) para remover o objeto da sessao, desta forma o Hibernate nao vai fazer o update.

    Reply to this comment
  2. |

    urubatan, a não ser que vc realmente precise que o objeto fique na sessao, é isto?

    Reply to this comment
  3. |

    sim, eu realmente preciso que o objeto fique na sessão, caso contrario o lazy loading não funciona …

    Reply to this comment
  4. |

    entendi… acho que falei besteira então :-)
    abraço

    Reply to this comment
  5. |

    Alguns pontos,

    O Hibernate até onde sei, só salva os filhos caso você coloque os Cascades. Outro detalhe, é que não se deve usar o FlushMode.NEVER(deprecated) e sim FlushMode.MANUAL.

    Reply to this comment
  6. |

    sim, mas eu preciso do cascade …
    e valeu a dica do FlushMode.MANUAL :D

    Reply to this comment
  7. |

    Oi .Urubatan … Gostaria de uma ajuda sua …se possivel … estou desenvolvendo meu projeto final relacionado a Java Speech .sintetizadores de voz … tive conhecimento atravez do google um topico do forum ( http://www.guj.com.br )

    Link do topico : http://www.guj.com.br/posts/list/1308.java

    na qual vc ajuda alguns users como proceder para o funcionamento do sintetizador … o problema é que os links que vc recomendou para obter o (ViaVoice SDK for Windows) e o (ViaVoice TTS SDK for Windows) …procurei bastante mas acho que nao estao mais disponiveis .. se vc tiver esses arquivos ou pudesse me ajudar em alguma coisa … Agradeceria bastante …

    Valeu .Abraços …

    Reply to this comment
  8. |

    tenho a seguinte situacao, uma classe anotada assim:

    @Transactional(readOnly = true)

    porem durante a execucao de alguns metodos desta classe tipo um LOAD, acaba realizando updates de outros objetos que estavam em estado de persistentes.

    e tenho as seguintes definicoes no meu arquivo xml

    Reply to this comment
  9. |

    Oi Urubatan,

    Estou desenvolvendo um projeto com Java Speech (Recognizer) e não existe mais disponível na Net o (ViaVoice SDK for Windows) e o (ViaVoice TTS SDK for Windows), onde posso encontrar ou comprar, não encontrei nem no site da IBM, existe algum que possa substituir?

    Obrigado pela ajuda.

    Lenio.

    Reply to this comment

Leave a Comment