org.hibernate.collection.PersistentSet (org.hibernate.collection.internal.PersistentSet in Hiberante4) 
keeps a reference to the original set passed to the constructor and also it does 
internally keep snapshots of the last set state.
When flushing hibernate checks if the snapshot size is equal to the size of the original set,
if not, the hibernate knows that the collection has become dirty (forceDirty = true) and it iterates again over the original set ...
Code:
PersistentSet.equalsSnapshot(CollectionPersister) line: 113   
CollectionEntry.dirty(PersistentCollection) line: 176   
CollectionEntry.preFlush(PersistentCollection) line: 196   
EJB3FlushEventListener(AbstractFlushingEventListener).prepareCollectionFlushes(PersistenceContext) line: 187   
EJB3FlushEventListener(AbstractFlushingEventListener).flushEverythingToExecutions(FlushEvent) line: 92   
EJB3FlushEventListener(DefaultFlushEventListener).onFlush(FlushEvent) line: 51   
SessionImpl.flush() line: 1127