Houve algumas discussões aqui sobre entidades JPA e qual hashCode()
/ equals()
implementação deve ser usada para classes de entidade JPA. A maioria (se não todos) deles depende do Hibernate, mas eu gostaria de discuti-los de maneira neutra na implementação do JPA (a propósito, estou usando o EclipseLink).
Todas as implementações possíveis estão tendo suas próprias vantagens e desvantagens em relação a:
hashCode()
/equals()
conformidade do contrato (imutabilidade) paraList
/Set
operações- Se objetos idênticos (por exemplo, de sessões diferentes, proxies dinâmicos de estruturas de dados carregadas lentamente) podem ser detectados
- Se as entidades se comportam corretamente no estado desanexado (ou não persistente)
Tanto quanto posso ver, existem três opções :
- Não os substitua; confiar
Object.equals()
eObject.hashCode()
hashCode()
/equals()
trabalho- Não é possível identificar objetos idênticos, problemas com proxies dinâmicos
- sem problemas com entidades desanexadas
- Substitua-os, com base na chave primária
hashCode()
/equals()
está quebrado- identidade correta (para todas as entidades gerenciadas)
- problemas com entidades desanexadas
- Substitua-os, com base no Business-Id (campos de chave não primária; e as chaves estrangeiras?)
hashCode()
/equals()
está quebrado- identidade correta (para todas as entidades gerenciadas)
- sem problemas com entidades desanexadas
Minhas perguntas são:
- Perdi uma opção e / ou ponto pro / con?
- Qual opção você escolheu e por quê?
ATUALIZAÇÃO 1:
Por " hashCode()
/ equals()
estão quebrados", quero dizer que sucessivas hashCode()
invocações pode retornar valores diferentes, o que é (quando corretamente implementado) não quebrado no sentido da Object
documentação da API, mas o que causa problemas ao tentar recuperar uma entidade mudou a partir de um Map
, Set
ou outro baseado em hash Collection
. Consequentemente, as implementações de JPA (pelo menos EclipseLink) não funcionarão corretamente em alguns casos.
ATUALIZAÇÃO 2:
Obrigado por suas respostas - a maioria delas tem uma qualidade notável.
Infelizmente, ainda não tenho certeza de qual abordagem será a melhor para um aplicativo da vida real ou como determinar a melhor abordagem para o meu aplicativo. Então, vou manter a questão em aberto e esperar mais discussões e / ou opiniões.
hashcode()
na mesma instância de objeto deve retornar o mesmo valor, a menos que quaisquer campos usados na equals()
implementação sejam alterados. Em outras palavras, se você tiver três campos em sua classe e seu equals()
método usar apenas dois para determinar a igualdade de instâncias, poderá esperar que o hashcode()
valor de retorno mude se você alterar um desses valores - o que faz sentido quando você considera que essa instância do objeto não é mais "igual" ao valor que a instância antiga representava.