이 콘텐츠는 선택한 언어로 제공되지 않습니다.
11.2.4. Considering Object Identity
An application can concurrently access the same persistent state in two different
Session
s. However, an instance of a persistent class is never shared between two Session
instances. It is for this reason that there are two different notions of identity:
- Database Identity
foo.getId().equals( bar.getId() )
- JVM Identity
foo==bar
For objects attached to a particular
Session
(i.e., in the scope of a Session
), the two notions are equivalent and JVM identity for database identity is guaranteed by Hibernate. While the application might concurrently access the "same" (persistent identity) business object in two different sessions, the two instances will actually be "different" (JVM identity). Conflicts are resolved using an optimistic approach and automatic versioning at flush/commit time.
This approach leaves Hibernate and the database to worry about concurrency. It also provides the best scalability, since guaranteeing identity in single-threaded units of work means that it does not need expensive locking or other means of synchronization. The application does not need to synchronize on any business object, as long as it maintains a single thread per
Session
. Within a Session
the application can safely use ==
to compare objects.
However, an application that uses
==
outside of a Session
might produce unexpected results. This might occur even in some unexpected places. For example, if you put two detached instances into the same Set
, both might have the same database identity (i.e., they represent the same row). JVM identity, however, is by definition not guaranteed for instances in a detached state. The developer has to override the equals()
and hashCode()
methods in persistent classes and implement their own notion of object equality. There is one caveat: never use the database identifier to implement equality. Use a business key that is a combination of unique, usually immutable, attributes. The database identifier will change if a transient object is made persistent. If the transient instance (usually together with detached instances) is held in a Set
, changing the hashcode breaks the contract of the Set
. Attributes for business keys do not have to be as stable as database primary keys; you only have to guarantee stability as long as the objects are in the same Set
. See the Hibernate website for a more thorough discussion of this issue. Please note that this is not a Hibernate issue, but simply how Java object identity and equality has to be implemented.