PooledOptimizer ID generation returns used values
Description
Attachments
Activity

Christian Beikov April 8, 2022 at 12:21 PM
It is a requirement that allocationSize and increment on the DB match, so closing this as rejected

Yordan Gigov February 26, 2016 at 11:22 PM
After going through more of your code, the essential problem seems to stem from the fact that the database sequence increment_by is smaller than the SequenceGenerator allocationSize. The sequence was created automatically when making the table with a bigserial
type. This of course wouldn't happen if we rely on schema generation from JPA.
You can mark this as a minor bug now , since there is a workaround of setting the allocationSize to the same as the corresponding value in the database, but that may be automated as well. For example in Postgre, the query would be
or
In the mean time, setting
is a working bypass without having to change all my entities.
However I just searched the docs at http://docs.jboss.org/hibernate/orm/5.0/userGuide/en-US/html_single/ and there is no mention of the id optimizer option. Anyone with load-balancing on multiple server instances would need to know this. We barely got a user base and we already had to expand Tomcat's memory limit to 2GB, because it ran out at 512MB.

Yordan Gigov February 26, 2016 at 6:26 PMEdited
The way I understood incrementSize
is that it's supposed to save us frequent queries to reserve an ID by synchronizing the in-JPA counter with the in-database one every incrementSize
inserts, or of course on shutdown.Alternatively it would be safer to first increment it by 50 in the database, then just wait for the in-JPA counter to catch-up. However by my count even if it's set to 1, under the current implementation it will fail the first persist when launched in an existing database, like when you're restarting the application. It will succeed the second time, but only for the same table until the next restart.
Another potential problem I thought of (but won't personally encounter any time soon) is if several server instances share the same database, say if they stand behind a load-balancer. The sequence caching will lead to de-synchronization between the two servers as soon as one of them persists an entity, the other one will try using the same ID. I just thought of a way to write a test for the load-balancing act.
Edit: I tried setting "hibernate.id.new_generator_mappings" to "false" and it fails on schema validation, even before the test.
That's not even the name I specified in the annotation.
Steve Ebersole February 26, 2016 at 5:36 PM
To be honest I am not sure how your current sequence value shows this is portable anyway. How is 130 a multiple of 50?
The spec is unfortunately very unclear on these points as it is on many points. It gets into what you think initialValue and incrementSize mean. And its easy to say that these are merely "schema export" hints, but keep in mind that these values existed way before JPA defined schema export. So I think that's not a valid PoV. And regardless, the spec is unclear as I said.

Yordan Gigov February 26, 2016 at 5:29 PM
I'll give that a try in a few hours, but I'm not convinced using more implementation-specific settings makes it more compliant with JPA, rather than less. The mentioned org.hibernate.cfg.AvailableSettings#USE_NEW_ID_GENERATOR_MAPPINGS
Javadoc doesn't really say what that change implies.
When attempting to persist an entity through EntityManager.persist, the sequence generator returns an old value. This causes a constraint violation and makes this version unusable for us. The field is defined as follows:
Within the database the value of the sequence is around 130, but the JPA attempts to persist it with an id that around 80 (both numbers increase on each attempt).
As far as I've been able to trace the problem, it comes from org.hibernate.id.enhanced.PooledOptimizer lines 88 and 89
Upon first firing of generate(), it sets the value to be 49 behind the actual sequence. A possible fix could be
However I haven't looked if the rest of the implementation keeps the value properly in sync with the database.
P.S. we are still using a custom build of 4.3.10 with 3 fixes to bypass the problems preventing us from using the official versions. Two other problems that impacted us have been fixed so far. I hope 5.0.9 will finally allow us to finally return to the official builds.