How does Hibernate detect dirty state of an entity object?
Hibernate default dirty checking mechanism will match all mapped properties of all currently attached entities against their initial loading-time values.
You can better visualize this process in the following diagram:
Hibernate does a field-by-field checking to determine the dirtiness of an entity.
So hashCode/equals do not come into the picture at all.
Actually, the field-by-field dirty checking done by Hibernate can be quite costly in terms of performance.
So it provides interfaces like Strategy or Interceptor.findDirty() to handle the same.
Following post explains this in greater detail (alongwith some ideas for applications to optimize it fully): http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp
Hibernate uses a strategy called inspection, which is basically this: when an object is loaded from the database a snapshot of it is kept in memory. When the session is flushed Hibernate compares the stored snapshot with the current state. If they differ the object is marked as dirty and a suitable SQL command is enqueued. If the object is still transient then it is always dirty.
Source: book Hibernate in Action (appendix B: ORM implementation strategies)
It's important to notice however that Hibernate's dirty-checking is independent of the methods equals/hascode. Hibernate does not look at these methods at all (except when using java.util.Set's, but this is unrelated to dirty-checking, only to the Collections API) The state snapshot I mentioned earlier is something similar to an array of values. It would be a very bad decision to leave such a core aspect of the framework in the hands of developers (to be honest, developers should not care about dirty-checking). Needless to say that equals/hascode can be implemented in many ways according to your needs. I recommend you to read the cited book, there the author discuss equals/hascode implementation strategies. Very insightful reading.