Ha habido algunas discusiones aquí acerca de las entidades JPA y qué hashCode()
/ equals()
implementación debería usarse para las clases de entidades JPA. La mayoría (si no todos) de ellos dependen de Hibernate, pero me gustaría discutirlos de manera neutral en la implementación de JPA (por cierto, estoy usando EclipseLink).
Todas las implementaciones posibles tienen sus propias ventajas y desventajas con respecto a:
hashCode()
/equals()
conformidad del contrato (inmutabilidad) paraList
/Set
operaciones- Si se pueden detectar objetos idénticos (por ejemplo, de diferentes sesiones, proxys dinámicos de estructuras de datos con carga lenta)
- Si las entidades se comportan correctamente en estado separado (o no persistente)
Hasta donde puedo ver, hay tres opciones :
- No los anule; confiar
Object.equals()
yObject.hashCode()
hashCode()
/equals()
trabajo- no puede identificar objetos idénticos, problemas con proxys dinámicos
- sin problemas con entidades separadas
- Anularlos, según la clave primaria
hashCode()
/equals()
están rotos- identidad correcta (para todas las entidades gestionadas)
- problemas con entidades separadas
- Anularlos, en función del ID de negocio (campos de clave no primarios; ¿qué pasa con las claves externas?)
hashCode()
/equals()
están rotos- identidad correcta (para todas las entidades gestionadas)
- sin problemas con entidades separadas
Mis preguntas son:
- ¿Perdí una opción y / o un punto pro / con?
- ¿Qué opción elegiste y por qué?
ACTUALIZACIÓN 1:
Por " hashCode()
/ equals()
están rotos", quiero decir que las sucesivas hashCode()
invocaciones pueden devolver valores diferentes, que es (cuando se implementa correctamente) no rota en el sentido de la Object
documentación de la API, pero que causa problemas al intentar recuperar una entidad cambió de una Map
, Set
u otra basado en hash Collection
. En consecuencia, las implementaciones JPA (al menos EclipseLink) no funcionarán correctamente en algunos casos.
ACTUALIZACIÓN 2:
Gracias por sus respuestas, la mayoría de ellas tienen una calidad notable.
Desafortunadamente, todavía no estoy seguro de qué enfoque será el mejor para una aplicación de la vida real o cómo determinar el mejor enfoque para mi aplicación. Por lo tanto, mantendré la pregunta abierta y espero más discusiones y / u opiniones.
hashcode()
a la misma instancia de objeto debería devolver el mismo valor, a menos que equals()
cambie cualquier campo utilizado en la implementación. En otras palabras, si tiene tres campos en su clase y su equals()
método usa solo dos de ellos para determinar la igualdad de instancias, entonces puede esperar que el hashcode()
valor de retorno cambie si cambia uno de los valores de ese campo, lo cual tiene sentido cuando considera que esta instancia de objeto ya no es "igual" al valor que representaba la instancia anterior.