Session.refresh doesn't return an instance, it updates the given instance in place. It does this by passing the optionalObject parameter to EntityPersister.load, identifying the object to be populated from the DB read. If the loader is a LegacyBatchingEntityLoader it disregards the optionalObject as it is going to load a batch of objects and optionalObject isn't supported in batch loads.
This means that the refresh operation in fact loads into a new instance, and the original instance is untouched. It isn't refreshed. And the session now contains the original instance and the new refreshed instance, but returns the new refreshed instance for subsequent calls to Session.get.
The problem this manifests, and how we detected this, is that any PersistentCollections in the instance are evicted (session set to null), and when we then try to access them an IllegalStateException is thrown because the session is null.
Hibernate 4.3.0, PostgreSQL 9.2 / 9.3