How does Hibernate distinguish between transient (i.e. newly instantiated) and detached objects

Hibernate uses the “version” property, if there is one.

If not uses the identifier value. No identifier value means a new object. This does work only for Hibernate managed surrogate keys. Does not work for natural keys and assigned (i.e. not managed by Hibernate) surrogate keys.