terça-feira, 31 de maio de 2011

Problema com equals em entidades usando Hibernate

Há uns meses atrás eu tive um problema com uma combo e motivo do problema era a falta de um equals na classe. As vezes quando a página era renderizada o objeto que estava selecionado era de uma instancia diferente do correspondente da lista e com isso dava inconsistência.

Por este motivo todas as classes precisam do equals e hashcode implementado e o eclipse gera eles automaticamente. Mas ontem eu tive um problema com este equals gerado de maneira automática, pois ele gera o equals dessa maneira:


@Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  UsuarioLogin other = (UsuarioLogin) obj;
  if (idUsuario != other.idUsuario)
   return false;
  return true;
 }


Este equals pode gerar dois problemas em nosso ambiente por conta de como o hibernate trabalha. O hibernate cria constantemente classes em tempo de execução que herdam das classes da entidade e adicionam métodos que ele precisa. Vocês que trabalharam com Hibernate já devem ter visto Objetos com classes estranhas como br.com.infox.cliente.entity.Pessoa_$$_javassist_26.

O primeiro problema é que como são classes diferentes esta comparação sempre retorna false: if (getClass() != obj.getClass()). Para resolver deve-se testar com instanceof.

O segundo problema é o acesso aos campo da entidade. As vezes mesmo campos que não são lazy, só são populados quando são chamados pelo get do campo, então a comparação (idProcesso != other.idProcesso) pode retornar false, pois o valor pode não estar populado ainda.

Eu tive esse dois problemas ontem com a classe UsuarioLogin, e perdi um bom tempo para descobri isso.

Para tornar nosso equals das entidades compatíveis com o hibernate podemos reescrever ele assim:




@Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (!(obj instanceof UsuarioLogin))
   return false;
  UsuarioLogin other = (UsuarioLogin) obj;
  if (getIdUsuario() != other.getIdUsuario())
   return false;
  return true;
 }

Maiores explicações sobre estes problemas podem ser lidas aqui: http://blog.xebia.com/2008/03/advanced-hibernate-proxy-pitfalls/

Meu ambiente de desenvolvimento em 7 itens

Recebi um convite publico do Hugo Doria e resolvi participar deste meme retirando um item.

1) Hardware e SO
Minha maquina de desenvolvimento aqui na Infox é um Dell Latitude E6500, com 4gb de memoria. Aqui utilizamos um monitor extra, que aumenta muito a produtividade.



2) Linguagens de Programação
Java é praticamente a unica linguagem que eu utilizo. No meu projeto aqui da Infox, trabalhamos com JavaServer Faces + Seam Framework + Hibernate.
Para quem programa em Java, recomendo pesquisar sobre o Seam. O mentor dele é nada menos que o Garvin King, o cara por trás do Hibernate e que ajudou com a especificação do JPA, quase o Chuck Norris do Java.

3) Editores e IDE
Utilizamos como IDE o Jboss Developer Studio (É um empacotamento do Eclipse feito pela Red Hat, o pacote já vem com o plugin Jboss Tools e já instala e configura o Jboss Server). Antes usávamos o Eclipse + Jboss Tools sem nenhum problema nenhum.

4) Controle de Versão
Atualmente utilizamos o SVN, no passado utilizávamos os CVS e na migração tivemos vários problemas com o Plugin do SVN pro Eclipse que ná época dava problemas regularmente.

5) Softwares.

  • Navegadores: No trabalho utilizo Firefox e IE (Por causa dos clientes claro), mas pessoalmente eu migrei do Firefox para o Chrome há alguns meses.
  • SQuirreL SQL Client: Ótimo software open source para quem trabalha criando consultas de banco de dados. Possui muito recursos e o auto completar acelera muito a criação das consultas.
  • Notepad++: Melhor editor de texto que já usei, bem robusto, aceita plugins, leve, etc.
  • Foobar2000: Player de áudio bem leve e com muitos recursos, eu pessoalmente gosto de programar escutando música.
6) Música
Gosto muito de trabalhar escutando música, ela ajuda muito a me isolar dos barulhos externos e me concentrar nas tarefas mais delicadas, alem de animar e relaxar ;)
Nas férias deste ano relaxei viajando para assistir dois shows: Ozzy e Iron Maiden!
Meu gosto musical é da vertente Rock and Roll -> Metal pendendo mais para o Metal. Escuto Iron Maiden, Megadeth, Slayer, Pink Floyd, etc até coisas bem mais pesadas como Deicide, Carcass e Dying Fetus ou outras mais lights como Raul Seixas.