Author: steve.ebersole(a)jboss.com
Date: 2010-05-12 14:19:00 -0400 (Wed, 12 May 2010)
New Revision: 19480
Modified:
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
Log:
HHH-5218 - Provide a new "pooled value" based optimizer which interprets the
database value as the low boundary instead of upper boundary
Modified:
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
===================================================================
---
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -434,9 +434,7 @@
* Find the column owner (ie PersistentClass or Join) of columnName.
* If columnName is null or empty, persistentClass is returned
*/
- public static Object findColumnOwner(
- PersistentClass persistentClass, String columnName, ExtendedMappings mappings
- ) {
+ public static Object findColumnOwner(PersistentClass persistentClass, String columnName,
ExtendedMappings mappings) {
if ( StringHelper.isEmpty( columnName ) ) {
return persistentClass; //shortcut for implicit referenced column names
}
@@ -475,9 +473,11 @@
* apply an id generator to a SimpleValue
*/
public static void makeIdGenerator(
- SimpleValue id, String generatorType, String generatorName, ExtendedMappings
mappings,
- Map<String, IdGenerator> localGenerators
- ) {
+ SimpleValue id,
+ String generatorType,
+ String generatorName,
+ ExtendedMappings mappings,
+ Map<String, IdGenerator> localGenerators) {
Table table = id.getTable();
table.setIdentifierValue( id );
//generator settings
@@ -520,7 +520,16 @@
params.setProperty( (String) elt.getKey(), (String) elt.getValue() );
}
}
- if ( "assigned".equals( generatorType ) ) id.setNullValue(
"undefined" );
+
+ if ( "assigned".equals( generatorType ) ) {
+ id.setNullValue( "undefined" );
+ }
+
+ final String pooledOptPreference = mappings.getConfigurationProperties().getProperty(
Environment.PREFER_POOLED_VALUES_LO );
+ if ( pooledOptPreference != null ) {
+ params.setProperty( Environment.PREFER_POOLED_VALUES_LO, pooledOptPreference );
+ }
+
id.setIdentifierGeneratorProperties( params );
}
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -519,6 +519,12 @@
public static final String JPAQL_STRICT_COMPLIANCE=
"hibernate.query.jpaql_strict_compliance";
+ /**
+ * When using pooled {@link org.hibernate.id.enhanced.Optimizer optimizers}, prefer
interpreting the
+ * database value as the lower (lo) boundary. The default is to interpret it as the
high boundary.
+ */
+ public static final String PREFER_POOLED_VALUES_LO =
"hibernate.id.optimizer.pooled.prefer_lo";
+
private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
private static final boolean ENABLE_BINARY_STREAMS;
private static final boolean ENABLE_REFLECTION_OPTIMIZER;
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -2091,6 +2091,11 @@
params.setProperty( childNode.attributeValue( "name" ),
childNode.getTextTrim() );
}
+ final String pooledOptPreference = mappings.getConfigurationProperties().getProperty(
Environment.PREFER_POOLED_VALUES_LO );
+ if ( pooledOptPreference != null ) {
+ params.setProperty( Environment.PREFER_POOLED_VALUES_LO, pooledOptPreference );
+ }
+
model.setIdentifierGeneratorProperties( params );
}
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id.enhanced;
@@ -46,6 +45,7 @@
public static final String HILO = "hilo";
public static final String LEGACY_HILO = "legacy-hilo";
public static final String POOL = "pooled";
+ public static final String POOL_LO = "pooled-lo";
private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
@@ -92,6 +92,9 @@
else if ( POOL.equals( type ) ) {
optimizerClassName = PooledOptimizer.class.getName();
}
+ else if ( POOL_LO.equals( type ) ) {
+ optimizerClassName = PooledLoOptimizer.class.getName();
+ }
else {
optimizerClassName = type;
}
@@ -386,6 +389,9 @@
* Note that this optimizer works essentially the same as the
* {@link HiLoOptimizer} except that here the bucket ranges are actually
* encoded into the database structures.
+ * <p/>
+ * Note if you prefer that the database value be interpreted as the bottom end of our
current range,
+ * then use the {@link PooledLoOptimizer} strategy
*/
public static class PooledOptimizer extends OptimizerSupport implements
InitialValueAwareOptimizer {
private IntegralDataTypeHolder hiValue;
@@ -463,4 +469,39 @@
this.initialValue = initialValue;
}
}
+
+ public static class PooledLoOptimizer extends OptimizerSupport {
+ private IntegralDataTypeHolder lastSourceValue; // last value read from db source
+ private IntegralDataTypeHolder value; // the current generator value
+
+ public PooledLoOptimizer(Class returnClass, int incrementSize) {
+ super( returnClass, incrementSize );
+ if ( incrementSize < 1 ) {
+ throw new HibernateException( "increment size cannot be less than 1" );
+ }
+ if ( log.isTraceEnabled() ) {
+ log.trace( "creating pooled optimizer (lo) with [incrementSize=" +
incrementSize + "; returnClass=" + returnClass.getName() + "]" );
+ }
+ }
+
+ public Serializable generate(AccessCallback callback) {
+ if ( lastSourceValue == null || ! value.lt( lastSourceValue.copy().add( incrementSize
) ) ) {
+ lastSourceValue = callback.getNextValue();
+ value = lastSourceValue.copy();
+ // handle cases where initial-value is less that one (hsqldb for instance).
+ while ( value.lt( 1 ) ) {
+ value.increment();
+ }
+ }
+ return value.makeValueThenIncrement();
+ }
+
+ public IntegralDataTypeHolder getLastSourceValue() {
+ return lastSourceValue;
+ }
+
+ public boolean applyIncrementSizeToSourceValues() {
+ return true;
+ }
+ }
}
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id.enhanced;
@@ -30,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.hibernate.cfg.Environment;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.HibernateException;
@@ -280,8 +280,13 @@
* @return The optimizer strategy (name)
*/
protected String determineOptimizationStrategy(Properties params, int incrementSize) {
- String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE :
OptimizerFactory.POOL;
- return PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+ // if the increment size is greater than one, we prefer pooled optimization; but we
+ // need to see if the user prefers POOL or POOL_LO...
+ String defaultPooledOptimizerStrategy = PropertiesHelper.getBoolean(
Environment.PREFER_POOLED_VALUES_LO, params, false )
+ ? OptimizerFactory.POOL_LO
+ : OptimizerFactory.POOL;
+ String defaultOptimizerStrategy = incrementSize <= 1 ? OptimizerFactory.NONE :
defaultPooledOptimizerStrategy;
+ return PropertiesHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy );
}
/**
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id.enhanced;
@@ -37,6 +36,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.hibernate.cfg.Environment;
import org.hibernate.engine.TransactionHelper;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.IdentifierGeneratorHelper;
@@ -65,14 +65,14 @@
* performing generation, which would mean that we would have a row in the generator
* table for each entity name. Or any configuration really; the setup is very flexible.
* <p/>
- * In this respect it is very simliar to the legacy
+ * In this respect it is very similar to the legacy
* {@link org.hibernate.id.MultipleHiLoPerTableGenerator} in terms of the
* underlying storage structure (namely a single table capable of holding
* multiple generator values). The differentiator is, as with
* {@link SequenceStyleGenerator} as well, the externalized notion
* of an optimizer.
* <p/>
- * <b>NOTE</b> that by default we use a single row for all genertators
(based
+ * <b>NOTE</b> that by default we use a single row for all generators (based
* on {@link #DEF_SEGMENT_VALUE}). The configuration parameter
* {@link #CONFIG_PREFER_SEGMENT_PER_ENTITY} can be used to change that to
* instead default to using a row for each entity name.
@@ -303,8 +303,14 @@
this.updateQuery = buildUpdateQuery();
this.insertQuery = buildInsertQuery();
- String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE :
OptimizerFactory.POOL;
- String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params,
defOptStrategy );
+
+ // if the increment size is greater than one, we prefer pooled optimization; but we
+ // need to see if the user prefers POOL or POOL_LO...
+ String defaultPooledOptimizerStrategy = PropertiesHelper.getBoolean(
Environment.PREFER_POOLED_VALUES_LO, params, false )
+ ? OptimizerFactory.POOL_LO
+ : OptimizerFactory.POOL;
+ final String defaultOptimizerStrategy = incrementSize <= 1 ? OptimizerFactory.NONE :
defaultPooledOptimizerStrategy;
+ final String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params,
defaultOptimizerStrategy );
optimizer = OptimizerFactory.buildOptimizer(
optimizationStrategy,
identifierType.getReturnedClass(),
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -31,6 +31,7 @@
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
+import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.Mapping;
import org.hibernate.id.IdentifierGenerator;
Modified:
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
===================================================================
---
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
package org.hibernate.id.enhanced;
import junit.framework.Assert;
@@ -100,35 +123,136 @@
public void testSubsequentPooledOptimizerUsage() {
// test the pooled optimizer in situation where the sequence is already beyond its
initial value on init.
// cheat by telling the sequence to start with 1000
- final SourceMock sequence = new SourceMock( 1000, 3, 5 );
+ final SourceMock sequence = new SourceMock( 1001, 3, 5 );
// but tell the optimizer the start-with is 1
final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL,
Long.class, 3, 1 );
assertEquals( 5, sequence.getTimesCalled() );
- assertEquals( 1000, sequence.getCurrentValue() );
+ assertEquals( 1001, sequence.getCurrentValue() );
Long next = (Long) optimizer.generate( sequence );
- assertEquals( 1000, next.intValue() );
+ assertEquals( 1001, next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
next = (Long) optimizer.generate( sequence );
- assertEquals( 1001, next.intValue() );
+ assertEquals( (1001+1), next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
next = (Long) optimizer.generate( sequence );
- assertEquals( 1002, next.intValue() );
+ assertEquals( (1001+2), next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
// force a "clock over"
next = (Long) optimizer.generate( sequence );
- assertEquals( 1003, next.intValue() );
+ assertEquals( (1001+3), next.intValue() );
assertEquals( (5+2), sequence.getTimesCalled() );
- assertEquals( (1000+6), sequence.getCurrentValue() );
+ assertEquals( (1001+6), sequence.getCurrentValue() );
}
+ public void testBasicPooledLoOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO,
Long.class, 3 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 2, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 3, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+// // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( (1+3), sequence.getCurrentValue() );
+ }
+
+ public void testSubsequentPooledLoOptimizerUsage() {
+ // test the pooled optimizer in situation where the sequence is already beyond its
initial value on init.
+ // cheat by telling the sequence to start with 1000
+ final SourceMock sequence = new SourceMock( 1001, 3, 5 );
+ // but tell the optimizer the start-with is 1
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL,
Long.class, 3, 1 );
+
+ assertEquals( 5, sequence.getTimesCalled() );
+ assertEquals( 1001, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+1), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+2), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+// // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+3), next.intValue() );
+ assertEquals( (5+2), sequence.getTimesCalled() );
+ assertEquals( (1001+6), sequence.getCurrentValue() );
+ }
+
+ public void testRecoveredPooledOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL,
Long.class, 3, 1 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( 4, sequence.getCurrentValue() );
+
+ // app ends, and starts back up (we should "lose" only 2 and 3 as id values)
+ final Optimizer optimizer2 = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL,
Long.class, 3, 1 );
+ next = ( Long ) optimizer2.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 3, sequence.getTimesCalled() );
+ assertEquals( 7, sequence.getCurrentValue() );
+ }
+
+ public void testRecoveredPooledLoOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO,
Long.class, 3, 1 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ // app ends, and starts back up (we should "lose" only 2 and 3 as id values)
+ final Optimizer optimizer2 = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO,
Long.class, 3, 1 );
+ next = ( Long ) optimizer2.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( 4, sequence.getCurrentValue() );
+ }
+
private static class SourceMock implements AccessCallback {
private IdentifierGeneratorHelper.BasicHolder value = new
IdentifierGeneratorHelper.BasicHolder( Long.class );
private long initialValue;
@@ -151,6 +275,7 @@
this.initialValue = 1;
}
else {
+ this.value.initialize( -1 );
this.initialValue = initialValue;
}
}
@@ -182,5 +307,4 @@
return value == null ? -1 : value.getActualLongValue();
}
}
-
}
Modified:
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
===================================================================
---
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12
17:17:45 UTC (rev 19479)
+++
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12
18:19:00 UTC (rev 19480)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
package org.hibernate.id.enhanced;
import java.util.Properties;
@@ -9,6 +32,7 @@
import org.hibernate.Hibernate;
import org.hibernate.MappingException;
+import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect;
@@ -179,7 +203,23 @@
assertClassAssignability( OptimizerFactory.PooledOptimizer.class,
generator.getOptimizer().getClass() );
Assert.assertEquals( 20, generator.getOptimizer().getIncrementSize() );
Assert.assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+ }
+ public void testPreferPooledLoSettingHonored() {
+ final Dialect dialect = new PooledSequenceDialect();
+
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class,
generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class,
generator.getOptimizer().getClass() );
+
+ props.setProperty( Environment.PREFER_POOLED_VALUES_LO, "true" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class,
generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledLoOptimizer.class,
generator.getOptimizer().getClass() );
}
private static class TableDialect extends Dialect {