I have a hash-based collection of objects, such as HashSet or HashMap. What issues can I run into when the implementation of hashCode() is such that it can change with time because it’s computed from some mutable fields?
How does it affect Hibernate? Is there any reason why having hashCode() return object’s ID by default is bad? All not-yet-persisted objects have id=0, if that matters.
What is the reasonable implementation of hashCode for Hibernate-mapped entities? Once set the ID is immutable, but it’s not true for the moment of saving an entity to database.
I’m not worried about performance of a HashSet with a dozen entities with key=0. What I care about is whether it’s safe for my application and Hibernate to use ID as hash code, because ID changes as it is generated on persist.
If the hash code of the same object changes over time, the results are basically unpredictable. Hash collections use the hash code to assign objects to buckets — if your hash code suddenly changes, the collection obviously doesn’t know, so it can fail to find an existing object because it hashes to a different bucket now.
Returning an object’s ID by itself isn’t bad, but if many of them have id=0 as you mentioned, it will reduce the performance of the hash table: all objects with the same hash code go into the same bucket, so your hash table is now no better than a linear list.
Update: Theoretically, your hash code can change as long as nobody else is aware of it — this implies exactly what @bestsss mentioned in his comment, which is to remove your object from any collections that may be holding it and insert it again once the hash code has changed. In practice, a better alternative is to generate your hash code from the actual content fields of your object rather than relying on the database ID.