The last comment on this thread http://opensource.atlassian.com/projects/hibernate/browse/HHH-1273 specifies it very well:
persist() is well defined. It makes a
transient instance persistent.
However, it doesn't guarantee that the
identifier value will be assigned to
the persistent instance immediately,
the assignment might happen at flush
time. The spec doesn't say that, which
is the problem I have with persist().
persist() also guarantees that it will
not execute an INSERT statement if it
is called outside of transaction
boundaries. This is useful in
long-running conversations with an
extended Session/persistence context.
A method like persist() is required.
save() does not guarantee the same, it
returns an identifier, and if an
INSERT has to be executed to get the
identifier (e.g. "identity" generator,
not "sequence"), this INSERT happens
immediately, no matter if you are
inside or outside of a transaction.
This is not good in a long-running
conversation with an extended
Session/persistence context.
Also it seems from what I could gather from other sources that an entity having cascade="persist" will cascade at the time of the call, not on flush. That might very useful too.