Hibernate - Comportamento estranho no UPDATE  XML
Índice dos Fóruns » Java Enterprise Edition (Java EE)
Autor Mensagem
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Boa noite pessoal, estou usando a versão 3.2.0cr2 do Hibernate e a versão 3.2.0cr1 do Hibernate Annotations.

Estou fazendo uma pequena aplicação para testar a combinação Mentawai + Hibernate. Surgiu um comportamento estranho no Hibernate que não estou sabendo identificar.

O problema é o seguinte...

Tenho a seguinte definição de tabela (Postgres 8.1)



Observem que o campo ds_nome tem que ser único.

O seguinte bean de mapeamento:



E tenho o seguinte método na minha classe HibernateContactDAO:



Vou simular o erro para vcs...

Imaginem que no BD tem 2 registros com ds_nome = "A" e ds_nome= "B" ,repectivamente.

Agora imaginem que o usuário carrega o objeto contact com o ds_nome="A", muda o nome para "B" e chama o método update().

Gera um erro de violação de constraint até aí normal.

agora o objeto contact está com ds_nome="B" (porque ao gerar o erro, o sistema volta para tela de cadastro com o campo input preenchido). O usário dá update novamente. BINGO! Dessa vez não dá erro nenhum.

Só para constar, não estou usando cache de segundo nível.

O que pode estar acontecendo!?

Guilherme Silveira
Administrador

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

1. o banco possui um bug e deixa a unique da coluna quebrar. eh isso que esta acontecendo?
2. o hibernate engole a exception do banco ao alterar tal coluna
3. o hibernate nao coloca o campo no statement de update

Seria interessante:

a) imprimir o sql gerado pelo hibernate
b) fazer tal sql na mao

Se esse sql gerar erro do banco, esquece (1) (mto provavel, certo?)
Se esse sql nao possui o campo no update (dynamic-update?), entao eh o (3)
Se esse sql possui o campo do update alterando a chave e gera o erro, entao eh (2)

Abraco

Guilherme

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

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Fala Guilherme! Então vamos aos pontos...



Esse não é. Qualquer violação de constraint o Postgres avisa na hora para qualquer situação.



Vamos lá. A explicação desse é um pouco mais extensa.
Imagina que no BD tenho dois registros (só vou colocar id_contato, e ds nome):

id_contato ds_nome

15 fulano
16 siclano

Tenho um form html com os os campos (só vou colocar os principais): id (hidden) e nome(text). Como é um update o id vai estar preenchido com o valor do registro no BD (e.g: 15) e suponhamos que o nome foi alterado com para o valor siclano.

Na minha action preencho um objeto contact (classe Contact) com os respectivos valores. Minha action chama o método update(Contact). O que acontece:

1) Contact c = (Contact)session.load(Contact.class,contact.getId()); c agora possui os valores que vieram do banco.

2) BeanUtils.copyProperties(c, contact); Copio os valores que vieram da requisição para c, ou seja a propriedade name foi alterada (fulano->siclano)

3) Commit. Acontece o esperado. O Hibernate caputra a exceção do banco e gera uma mensagem de violação de constraint. Minha action retorna um ERROR que faz voltar para a tela de cadastro.

No formulário html o id (hidden) ainda estará com o valor 15, já o campo nome estará com o valor siclano (gerador do erro). Daí submeto o form novamente. Agora que acontece o comportamento estranho:

1) Contact c = (Contact)session.load(Contact.class,contact.getId()); c não traz os valores do banco e sim o valor da última alteração, ou seja, c.id = 15 e c.name = siclano (Pq não trouxe o valor do banco?)

2) BeanUtils.copyProperties(c, contact); Copio os valores que vieram da requisição para c, neste caso a propriedade name do objeto para o Hibernate não foi alterada.

3) Commit. Não gera erro nenhum. Pois para o Hibernate não houve alteração no objeto.

No banco a coluna ds_nome do registro com id_contato = 15 continua fulano, porém na aplicação pela listagem do hibernate aparecem dois siclanos. Copio o mesmo select que ele executa e coloco no banco vem tudo certo ((15, fulano),(16,siclano)).




Pelo sql que ele gerou. Está colocando o campo direitinho no update. Lembrando que no segundo submit ele não executa update pois para ele não houve alteração no objeto.

E aí pessoal? Alguma idéia!?
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

É muito parecido com esse provável bug aqui:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1808

Com umas pequenas diferenças:
- Com ou sem o ehcache o problema continua
- não estou usando o executeUpdate (pelo menos não diretamente)

Um problema desse tipo em produção é que deixa o cara maluco
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Encontrei uma coisa interessante na documentação do hibernate:






O trecho "and close the Session immediately" me chamou a atenção. O mentawai SEMPRE fecha a sessão mesmo em caso de exceções geradas pelo Hibernate!? Vou investigar isso. Se alguém já souber responder vai ajudar muito.
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

" O método afterConsequence será chamado pelo filtro após a execução da consequencia da action. Repare que esse método será executado mesmo que haja um exception e a consequência não seja totalmente executada."



Acho que o Menta está correto. Será que é mesmo um bug do Hibernate!?
saoj
JWizard
[Avatar]

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

Tá usando a versão 1.4 do menta, a última onde o afterConsequence está sendo usado ?


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]
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Estou saoj.

http://www.mentaframework.org/mentawai-1.4.zip

E testei com o beta também.

http://www.mentaframework.org/beta/mentawai.jar

Teria alguma possibilidade do AfterConsequence não está sendo chamado!?
saoj
JWizard
[Avatar]

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


Teria alguma possibilidade do AfterConsequence não está sendo chamado!?


Não. Tem outras pessoas usando isso sem problema. Após a execução do forward (consequencia) a session será fechada.

Acho que tu vai ter que fazer o que o Guilherme falou.

Faz um código isolado, só hibernate que faz isso aí que vc está querendo e tenta entender o que acontece. Bem-vindo ao Hibernate !!!!




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]
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Eu tenho um projeto rodando a mais de 1 ano com a versão 3.0 e nunca tive problemas. Inventei de baixar a 3.2.0cr2 e tou batendo cabeça.

Valeu mesmo pessoal! Vou isolar o problema e os resultados posto aqui.
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Olha eu de novo pessoal!

Só tive tempo de isolar o problema agora. Tenho uma notícia boa, usando somente o Hibernate funciona.



Agora vou tentar descobrir onde está o problema na integração com o Mentawai.
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Descobriiiiiii!!!!!!!!!!!

O Mentawai não está chamando o método afterConsequence do HibernateFilter.

Alterei a classe do Mentawai para exibir na tela mensagem de abertura e fechamento da sessão que constatei que ele só faz a abertura mas não o fechamento.

Se não usar o HibernateFilter e controlar a sessão manualmente como fiz no exemplo acima funciona normalmente.

Espero ter ajudado
 Nome do arquivo HibernateFilter.java [Disk] Download
 Descrição Coloquei uns System.out para visualizar o que estava acontecendo.
 Tamanho 5 Kbytes
 Baixado:  74 vez(es)

saoj
JWizard
[Avatar]

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

Putz !!!!

Posta o seu ApplicationManager lá no site do mentawai urgente...


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]
ranophoenix
JavaEvangelist
[Avatar]

Membro desde: 28/02/2004 22:49:47
Mensagens: 389
Offline

Está lá

http://forum.mentaframework.org/posts/list/0/383.page#2638
saoj
JWizard
[Avatar]

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


jar corrigido em:

http://www.mentaframework.org/beta/mentawai.jar

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 » Java Enterprise Edition (Java EE)
Ir para:   
Powered by JForum 2.1.8 © JForum Team