The id must be generated prior to the insert statement because of the
write-behind transactional cache. Behind the scenes, Hibernate uses a Map-like structure to cache all managed entities in what's commonly called the 1st-level cache. The cache key is formed of the Entity class and the Entity identifier, hence the identifier must be known when the entity becomes managed.
Also worth mentioning that when you
persist an entity, the insert statement is not generated right away. The insert statement is delayed until a flush occurs.
If you want to optimize the number of sequence calls, you should use the
pooled optimizer.