Una aplicación puede acceder
simultáneamente al mismo estado persistente en dos Sessiones diferentes. Sin embargo, una instancia
de una clase persistente nunca se comparte entre dos instancias de Session. Por lo tanto,
existen dos nociones diferentes de identidad:
Identidad de Base de Datos
foo.getId().equals( bar.getId() )
Identidad JVM
foo==bar
Para los objetos unidos a una Session
en particular (por ejemplo, en el ámbito de una Session) las dos nociones son equivalentes y la
identidad de la JVM para la identidad de la base de datos se encuentra garantizada por Hibernate.
Mientras la aplicación acceda simultáneamente al "mismo" objeto (identidad persistente) en dos
sesiones diferentes, las dos instancias serán
realmente "diferentes" (identidad JVM). Los conflictos se resuelven
usando un enfoque optimista y el versionado automático.
Este enfoque deja que Hibernate y la
base de datos se preocupen de la concurrencia. Además provee la mejor escalabilidad, ya que
garantizando la identidad en unidades de trabajo monohilo no necesitan bloqueos caros u otros
medios de sincronización. La aplicación no necesita sincronizar sobre ningún objeto,
siempre que se mantenga un solo hilo por Session.
Dentro de una Session la aplicación
puede usar con seguridad == para comparar objetos. Sin embargo, una aplicación que usa ==
fuera de una Session, podría ver resultados inesperados. Esto podría ocurrir incluso en sitios
algo inesperados. Por ejemplo, si pone dos instancias separadas dentro del mismo Set ambas
podrían tener la misma identidad de la base de datos (por ejemplo, representar la misma
fila). Sin embargo, la identidad JVM, por definición, no está garantizada para las instancias en
estado separado.
El desarrollador tiene que sobrescribir
los
métodos equals() y hashCode() en las clases persistentes e
implementar su propia noción
de igualdad de objetos. Nunca se
debería usar el identificador de la base de datos
para implementar
la igualdad. Use una clave de negocio, una combinación de atributos
únicos,
usualmente inmutables. El identificador de la base de datos
cambiará si un objeto transitorio es
hecho persistente. Si la
instancia transitoria (usualmente junto a las instancias separadas)
es
mantenida en un Set, cambiar el código hash rompe el contrato
del Set. Los atributos para las
claves empresariales no tienen que
ser tan estables como las claves principales de la base de datos, sólo tiene que garantizar
estabilidad en tanto los objetos estén en el mismo Set.
Este no es problema de Hibernate, sino
que simplemente se tiene que implementar la identidad y la igualdad de los objetos Java.