|
I think I have spotted a bug in the HiLo implementation.
When the bucket has reached its limit, a new last source value is retrieved from the HiLo table. The upper limit is then set, but the current value is never set to the new bucket start value. This means that if there is more than one process using the same HiLo sequence, the HiLo values could start overlapping.
package org.hibernate.id.enhanced;
public class HiLoOptimizer extends AbstractOptimizer {
...
@Override
public synchronized Serializable generate(AccessCallback callback) {
final GenerationState generationState = locateGenerationState( callback.getTenantIdentifier() );
if ( generationState.lastSourceValue == null ) {
generationState.lastSourceValue = callback.getNextValue();
while ( generationState.lastSourceValue.lt( 1 ) ) {
generationState.lastSourceValue = callback.getNextValue();
}
generationState.upperLimit = generationState.lastSourceValue.copy().multiplyBy( incrementSize ).increment();
generationState.value = generationState.upperLimit.copy().subtract( incrementSize );
}
else if ( ! generationState.upperLimit.gt( generationState.value ) ) {
generationState.lastSourceValue = callback.getNextValue();
generationState.upperLimit = generationState.lastSourceValue.copy().multiplyBy( incrementSize ).increment();
//SHOULD SET generationState.value HERE
}
return generationState.value.makeValueThenIncrement();
}
..
}
|