Reputation: 4476
I decided to make use of a Hibernate id generator which meet the following requirements: - safe id generation when the domain is accessed from different applications(different JVMs) - make use of id intervals (do not query the database every time a new ID is needed)
After some investigations I choose one of 2 hibernate enhanced identifier generators, it's the
org.hibernate.id.enhanced.TableGenerator
The problem is that this algorithm keep in database not the next value available but the end of the next available interval, so, let's say I have an id generator with increment_size 10, when i make a request for an id I receive the interval 1 - 10, but in the database is now stored not the value 11, but 21. With this behavior I have to keep the increment_size the same along all classes that map to a specific table. Why does it have this behavior ? Is there any way to fix this ?
Upvotes: 4
Views: 3861
Reputation: 13
This post is old but for others that may have the same kind of problem.
As indicated by Steve Ebersole, you should used "pooled-lo" optimizer in your case. Check also your hibernate version, it should be >= 4.3.11 because there was an issue in previous versions.
To give some explanation, with pooled-lo optimizer, the value stored in the database is the low value of the next interval available.
So if the id of the last entity persisted is in [1;10], the next interval available is [11,20] and the value stored in database will be 11, as you were expecting.
Thus if you have another program that don't use hibernate and is not even aware of the increment size defined in hibernate configuration, it will still be able to insert entities without breaking the sequence.
All it will have to do is to atomically get the sequence value and increment it, and then use the value retrieve (before the "incrementation") as the new entity id it wants to insert. In our example in order to insert one line, it will update the sequence value to 12 and add the new entity with the id 11. Thus when hibernate will reach the last id of its current interval in memory (10), it will query the database and store the value 22 in order to keep for it self the new interval of id [12;21].
Upvotes: 1
Reputation: 9443
org.hibernate.id.enhanced.TableGenerator defines a table that is capable of generating multiple values simultaneously. Sounds like you try to have it generate identifiers from just a single value for multiple entities. This is controlled by the 'segment_value' TableGenerator config setting, if you wanted to take advantage of it.
And as for the values, there is nothing to "fix". Its not broken. If you want different behavior, configure different behavior. This is controlled by something called an optimizer, defined by the TableGenerator 'optimizer' config setting. This is all covered in the manual : http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#mapping-declaration-id See specifically the section "5.1.2.3. Enhanced identifier generators" and "5.1.2.3.1. Identifier generator optimization". The manual does not talk about all the available optimizers. Sounds like the one you want is called "pooled-lo", which is just like "pooled", but stores the lo value rather than the high value.
Upvotes: 4