From ca46d28db374df53322707fdf0598e8672d5d3ab Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 6 Nov 2015 10:34:31 -0600 Subject: [PATCH] HHH-10219 - Infinite loop generating IDs if using negative increment (cherry picked from commit cd7212a1e8f658f26f3674140cc511fd20b6590b) --- .../hibernate/id/enhanced/NoopOptimizer.java | 9 +++++--- .../id/enhanced/OptimizerUnitTest.java | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/NoopOptimizer.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/NoopOptimizer.java index 2812c9c833..92c7924d82 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/NoopOptimizer.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/NoopOptimizer.java @@ -37,10 +37,13 @@ public final class NoopOptimizer extends AbstractOptimizer { // reliable as it might be mutated by multipled threads. // The lastSourceValue field is only accessed by tests, // so this is not a concern. - IntegralDataTypeHolder value = null; - while ( value == null || value.lt( 1 ) ) { - value = callback.getNextValue(); + IntegralDataTypeHolder value = callback.getNextValue(); + if ( incrementSize > 0 ) { + while ( value.lt( 1 ) ) { + value = callback.getNextValue(); + } } + lastSourceValue = value; return value.makeValue(); } diff --git a/hibernate-core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java b/hibernate-core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java index 90760a9efc..780be830f2 100644 --- a/hibernate-core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java +++ b/hibernate-core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java @@ -42,6 +42,28 @@ public class OptimizerUnitTest extends BaseUnitTestCase { assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially assertEquals( 10, sequence.getCurrentValue() ); } + @Test + public void testBasicNoOptimizerUsageWithNegativeValues() { + // test historic sequence behavior, where the initial values start at 1... + SourceMock sequence = new SourceMock( -1, -1 ); + Optimizer optimizer = buildNoneOptimizer( -1, -1 ); + for ( int i = 1; i < 11; i++ ) { + final Long next = ( Long ) optimizer.generate( sequence ); + assertEquals( -i, next.intValue() ); + } + assertEquals( 10, sequence.getTimesCalled() ); + assertEquals( -10, sequence.getCurrentValue() ); + + // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value) + sequence = new SourceMock( 0 ); + optimizer = buildNoneOptimizer( -1, 1 ); + for ( int i = 1; i < 11; i++ ) { + final Long next = ( Long ) optimizer.generate( sequence ); + assertEquals( i, next.intValue() ); + } + assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially + assertEquals( 10, sequence.getCurrentValue() ); + } @Test public void testBasicHiLoOptimizerUsage() {