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/Setoperaçõ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 Objectdocumentação da API, mas o que causa problemas ao tentar recuperar uma entidade mudou a partir de um Map, Setou 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.
