Quote:
In short, when we want to reattach detached objects in another session, not knowing for sure whether they are new or not (so I want hibernate to decide whether it is a new instance or an existing one), I should be using merge() instead of saveOrUpdate().
No, both are transparent wether the object (graph) you are passing in is transient or detached. The guaranteed state of your data is to be persistent afterwards.
saveOrUpdate() simply reattaches the detached instance - it is considered persistent again. (Or it tries to make transient stuff persistent, but that's not the issue.)
Reattachment might clash with an identical persistent instance (database identity) that is already in the Session, for whatever reason (already loaded, for example). This is why you need the merge() model, if you can't guarantee that the Session does not contain an identical instance when you saveOrUpdate().
merge() merges data and returns a persistent instance, depending on a set of rules as outlined in the docs.
Both allow different programming models and are used separate or together. The old method name for merge() was saveOrUpdateCopy() in native Hibernate. EJB 3.0 persistence only supports the merge() model.